summaryrefslogtreecommitdiffstats
path: root/libraries/logic
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/logic')
-rw-r--r--libraries/logic/AbstractCommonModel.cpp133
-rw-r--r--libraries/logic/AbstractCommonModel.h462
-rw-r--r--libraries/logic/BaseConfigObject.cpp103
-rw-r--r--libraries/logic/BaseConfigObject.h50
-rw-r--r--libraries/logic/BaseInstaller.cpp61
-rw-r--r--libraries/logic/BaseInstaller.h46
-rw-r--r--libraries/logic/BaseInstance.cpp270
-rw-r--r--libraries/logic/BaseInstance.h243
-rw-r--r--libraries/logic/BaseVersion.h59
-rw-r--r--libraries/logic/BaseVersionList.cpp104
-rw-r--r--libraries/logic/BaseVersionList.h126
-rw-r--r--libraries/logic/CMakeLists.txt344
-rw-r--r--libraries/logic/Commandline.cpp483
-rw-r--r--libraries/logic/Commandline.h252
-rw-r--r--libraries/logic/DefaultVariable.h35
-rw-r--r--libraries/logic/Env.cpp222
-rw-r--r--libraries/logic/Env.h60
-rw-r--r--libraries/logic/Exception.h34
-rw-r--r--libraries/logic/FileSystem.cpp436
-rw-r--r--libraries/logic/FileSystem.h123
-rw-r--r--libraries/logic/GZip.cpp115
-rw-r--r--libraries/logic/GZip.h12
-rw-r--r--libraries/logic/InstanceList.cpp580
-rw-r--r--libraries/logic/InstanceList.h187
-rw-r--r--libraries/logic/Json.cpp272
-rw-r--r--libraries/logic/Json.h249
-rw-r--r--libraries/logic/MMCStrings.cpp76
-rw-r--r--libraries/logic/MMCStrings.h10
-rw-r--r--libraries/logic/MMCZip.cpp491
-rw-r--r--libraries/logic/MMCZip.h88
-rw-r--r--libraries/logic/NullInstance.h90
-rw-r--r--libraries/logic/QObjectPtr.h78
-rw-r--r--libraries/logic/RWStorage.h60
-rw-r--r--libraries/logic/RecursiveFileSystemWatcher.cpp111
-rw-r--r--libraries/logic/RecursiveFileSystemWatcher.h63
-rw-r--r--libraries/logic/SeparatorPrefixTree.h298
-rw-r--r--libraries/logic/TypeMagic.h37
-rw-r--r--libraries/logic/Version.cpp140
-rw-r--r--libraries/logic/Version.h110
-rw-r--r--libraries/logic/java/JavaChecker.cpp159
-rw-r--r--libraries/logic/java/JavaChecker.h54
-rw-r--r--libraries/logic/java/JavaCheckerJob.cpp45
-rw-r--r--libraries/logic/java/JavaCheckerJob.h84
-rw-r--r--libraries/logic/java/JavaInstall.cpp28
-rw-r--r--libraries/logic/java/JavaInstall.h38
-rw-r--r--libraries/logic/java/JavaInstallList.cpp186
-rw-r--r--libraries/logic/java/JavaInstallList.h71
-rw-r--r--libraries/logic/java/JavaUtils.cpp219
-rw-r--r--libraries/logic/java/JavaUtils.h43
-rw-r--r--libraries/logic/java/JavaVersion.cpp112
-rw-r--r--libraries/logic/java/JavaVersion.h30
-rw-r--r--libraries/logic/launch/LaunchStep.cpp27
-rw-r--r--libraries/logic/launch/LaunchStep.h48
-rw-r--r--libraries/logic/launch/LaunchTask.cpp228
-rw-r--r--libraries/logic/launch/LaunchTask.h122
-rw-r--r--libraries/logic/launch/LoggedProcess.cpp163
-rw-r--r--libraries/logic/launch/LoggedProcess.h76
-rw-r--r--libraries/logic/launch/MessageLevel.cpp36
-rw-r--r--libraries/logic/launch/MessageLevel.h28
-rw-r--r--libraries/logic/launch/steps/CheckJava.cpp92
-rw-r--r--libraries/logic/launch/steps/CheckJava.h41
-rw-r--r--libraries/logic/launch/steps/LaunchMinecraft.cpp154
-rw-r--r--libraries/logic/launch/steps/LaunchMinecraft.h48
-rw-r--r--libraries/logic/launch/steps/ModMinecraftJar.cpp44
-rw-r--r--libraries/logic/launch/steps/ModMinecraftJar.h39
-rw-r--r--libraries/logic/launch/steps/PostLaunchCommand.cpp84
-rw-r--r--libraries/logic/launch/steps/PostLaunchCommand.h39
-rw-r--r--libraries/logic/launch/steps/PreLaunchCommand.cpp85
-rw-r--r--libraries/logic/launch/steps/PreLaunchCommand.h39
-rw-r--r--libraries/logic/launch/steps/TextPrint.cpp29
-rw-r--r--libraries/logic/launch/steps/TextPrint.h43
-rw-r--r--libraries/logic/launch/steps/Update.cpp50
-rw-r--r--libraries/logic/launch/steps/Update.h41
-rw-r--r--libraries/logic/minecraft/AssetsUtils.cpp230
-rw-r--r--libraries/logic/minecraft/AssetsUtils.h48
-rw-r--r--libraries/logic/minecraft/GradleSpecifier.h129
-rw-r--r--libraries/logic/minecraft/JarMod.h12
-rw-r--r--libraries/logic/minecraft/Library.cpp239
-rw-r--r--libraries/logic/minecraft/Library.h184
-rw-r--r--libraries/logic/minecraft/MinecraftInstance.cpp369
-rw-r--r--libraries/logic/minecraft/MinecraftInstance.h69
-rw-r--r--libraries/logic/minecraft/MinecraftProfile.cpp610
-rw-r--r--libraries/logic/minecraft/MinecraftProfile.h200
-rw-r--r--libraries/logic/minecraft/MinecraftVersion.cpp215
-rw-r--r--libraries/logic/minecraft/MinecraftVersion.h119
-rw-r--r--libraries/logic/minecraft/MinecraftVersionList.cpp591
-rw-r--r--libraries/logic/minecraft/MinecraftVersionList.h72
-rw-r--r--libraries/logic/minecraft/Mod.cpp377
-rw-r--r--libraries/logic/minecraft/Mod.h134
-rw-r--r--libraries/logic/minecraft/ModList.cpp616
-rw-r--r--libraries/logic/minecraft/ModList.h160
-rw-r--r--libraries/logic/minecraft/MojangDownloadInfo.h71
-rw-r--r--libraries/logic/minecraft/MojangVersionFormat.cpp381
-rw-r--r--libraries/logic/minecraft/MojangVersionFormat.h25
-rw-r--r--libraries/logic/minecraft/OpSys.cpp42
-rw-r--r--libraries/logic/minecraft/OpSys.h37
-rw-r--r--libraries/logic/minecraft/ParseUtils.cpp34
-rw-r--r--libraries/logic/minecraft/ParseUtils.h11
-rw-r--r--libraries/logic/minecraft/ProfilePatch.h104
-rw-r--r--libraries/logic/minecraft/ProfileStrategy.h35
-rw-r--r--libraries/logic/minecraft/ProfileUtils.cpp191
-rw-r--r--libraries/logic/minecraft/ProfileUtils.h25
-rw-r--r--libraries/logic/minecraft/Rule.cpp93
-rw-r--r--libraries/logic/minecraft/Rule.h101
-rw-r--r--libraries/logic/minecraft/VersionBuildError.h58
-rw-r--r--libraries/logic/minecraft/VersionFile.cpp60
-rw-r--r--libraries/logic/minecraft/VersionFile.h195
-rw-r--r--libraries/logic/minecraft/VersionFilterData.cpp75
-rw-r--r--libraries/logic/minecraft/VersionFilterData.h32
-rw-r--r--libraries/logic/minecraft/World.cpp385
-rw-r--r--libraries/logic/minecraft/World.h83
-rw-r--r--libraries/logic/minecraft/WorldList.cpp355
-rw-r--r--libraries/logic/minecraft/WorldList.h125
-rw-r--r--libraries/logic/minecraft/auth/AuthSession.cpp30
-rw-r--r--libraries/logic/minecraft/auth/AuthSession.h51
-rw-r--r--libraries/logic/minecraft/auth/MojangAccount.cpp278
-rw-r--r--libraries/logic/minecraft/auth/MojangAccount.h173
-rw-r--r--libraries/logic/minecraft/auth/MojangAccountList.cpp427
-rw-r--r--libraries/logic/minecraft/auth/MojangAccountList.h201
-rw-r--r--libraries/logic/minecraft/auth/YggdrasilTask.cpp255
-rw-r--r--libraries/logic/minecraft/auth/YggdrasilTask.h150
-rw-r--r--libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp202
-rw-r--r--libraries/logic/minecraft/auth/flows/AuthenticateTask.h46
-rw-r--r--libraries/logic/minecraft/auth/flows/RefreshTask.cpp144
-rw-r--r--libraries/logic/minecraft/auth/flows/RefreshTask.h44
-rw-r--r--libraries/logic/minecraft/auth/flows/ValidateTask.cpp61
-rw-r--r--libraries/logic/minecraft/auth/flows/ValidateTask.h47
-rw-r--r--libraries/logic/minecraft/forge/ForgeInstaller.cpp458
-rw-r--r--libraries/logic/minecraft/forge/ForgeInstaller.h52
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersion.cpp55
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersion.h42
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersionList.cpp450
-rw-r--r--libraries/logic/minecraft/forge/ForgeVersionList.h90
-rw-r--r--libraries/logic/minecraft/forge/ForgeXzDownload.cpp358
-rw-r--r--libraries/logic/minecraft/forge/ForgeXzDownload.h59
-rw-r--r--libraries/logic/minecraft/forge/LegacyForge.cpp56
-rw-r--r--libraries/logic/minecraft/forge/LegacyForge.h25
-rw-r--r--libraries/logic/minecraft/ftb/FTBPlugin.cpp395
-rw-r--r--libraries/logic/minecraft/ftb/FTBPlugin.h13
-rw-r--r--libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp128
-rw-r--r--libraries/logic/minecraft/ftb/FTBProfileStrategy.h21
-rw-r--r--libraries/logic/minecraft/ftb/FTBVersion.h32
-rw-r--r--libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp27
-rw-r--r--libraries/logic/minecraft/ftb/LegacyFTBInstance.h17
-rw-r--r--libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp138
-rw-r--r--libraries/logic/minecraft/ftb/OneSixFTBInstance.h30
-rw-r--r--libraries/logic/minecraft/legacy/LegacyInstance.cpp453
-rw-r--r--libraries/logic/minecraft/legacy/LegacyInstance.h142
-rw-r--r--libraries/logic/minecraft/legacy/LegacyUpdate.cpp393
-rw-r--r--libraries/logic/minecraft/legacy/LegacyUpdate.h70
-rw-r--r--libraries/logic/minecraft/legacy/LwjglVersionList.cpp189
-rw-r--r--libraries/logic/minecraft/legacy/LwjglVersionList.h156
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp142
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h39
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp276
-rw-r--r--libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h119
-rw-r--r--libraries/logic/minecraft/onesix/OneSixInstance.cpp597
-rw-r--r--libraries/logic/minecraft/onesix/OneSixInstance.h117
-rw-r--r--libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp418
-rw-r--r--libraries/logic/minecraft/onesix/OneSixProfileStrategy.h26
-rw-r--r--libraries/logic/minecraft/onesix/OneSixUpdate.cpp342
-rw-r--r--libraries/logic/minecraft/onesix/OneSixUpdate.h67
-rw-r--r--libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp225
-rw-r--r--libraries/logic/minecraft/onesix/OneSixVersionFormat.h22
-rw-r--r--libraries/logic/net/ByteArrayDownload.cpp105
-rw-r--r--libraries/logic/net/ByteArrayDownload.h48
-rw-r--r--libraries/logic/net/CacheDownload.cpp192
-rw-r--r--libraries/logic/net/CacheDownload.h63
-rw-r--r--libraries/logic/net/HttpMetaCache.cpp273
-rw-r--r--libraries/logic/net/HttpMetaCache.h125
-rw-r--r--libraries/logic/net/MD5EtagDownload.cpp155
-rw-r--r--libraries/logic/net/MD5EtagDownload.h52
-rw-r--r--libraries/logic/net/NetAction.h96
-rw-r--r--libraries/logic/net/NetJob.cpp125
-rw-r--r--libraries/logic/net/NetJob.h117
-rw-r--r--libraries/logic/net/PasteUpload.cpp99
-rw-r--r--libraries/logic/net/PasteUpload.h50
-rw-r--r--libraries/logic/net/URLConstants.cpp16
-rw-r--r--libraries/logic/net/URLConstants.h40
-rw-r--r--libraries/logic/news/NewsChecker.cpp135
-rw-r--r--libraries/logic/news/NewsChecker.h107
-rw-r--r--libraries/logic/news/NewsEntry.cpp77
-rw-r--r--libraries/logic/news/NewsEntry.h65
-rw-r--r--libraries/logic/notifications/NotificationChecker.cpp130
-rw-r--r--libraries/logic/notifications/NotificationChecker.h63
-rw-r--r--libraries/logic/pathmatcher/FSTreeMatcher.h21
-rw-r--r--libraries/logic/pathmatcher/IPathMatcher.h12
-rw-r--r--libraries/logic/pathmatcher/MultiMatcher.h31
-rw-r--r--libraries/logic/pathmatcher/RegexpMatcher.h42
-rw-r--r--libraries/logic/resources/Resource.cpp155
-rw-r--r--libraries/logic/resources/Resource.h132
-rw-r--r--libraries/logic/resources/ResourceHandler.cpp28
-rw-r--r--libraries/logic/resources/ResourceHandler.h36
-rw-r--r--libraries/logic/resources/ResourceObserver.cpp55
-rw-r--r--libraries/logic/resources/ResourceObserver.h73
-rw-r--r--libraries/logic/resources/ResourceProxyModel.cpp89
-rw-r--r--libraries/logic/resources/ResourceProxyModel.h39
-rw-r--r--libraries/logic/screenshots/ImgurAlbumCreation.cpp90
-rw-r--r--libraries/logic/screenshots/ImgurAlbumCreation.h44
-rw-r--r--libraries/logic/screenshots/ImgurUpload.cpp114
-rw-r--r--libraries/logic/screenshots/ImgurUpload.h33
-rw-r--r--libraries/logic/screenshots/Screenshot.h19
-rw-r--r--libraries/logic/settings/INIFile.cpp151
-rw-r--r--libraries/logic/settings/INIFile.h38
-rw-r--r--libraries/logic/settings/INISettingsObject.cpp107
-rw-r--r--libraries/logic/settings/INISettingsObject.h66
-rw-r--r--libraries/logic/settings/OverrideSetting.cpp54
-rw-r--r--libraries/logic/settings/OverrideSetting.h46
-rw-r--r--libraries/logic/settings/PassthroughSetting.cpp66
-rw-r--r--libraries/logic/settings/PassthroughSetting.h45
-rw-r--r--libraries/logic/settings/Setting.cpp53
-rw-r--r--libraries/logic/settings/Setting.h119
-rw-r--r--libraries/logic/settings/SettingsObject.cpp142
-rw-r--r--libraries/logic/settings/SettingsObject.h214
-rw-r--r--libraries/logic/status/StatusChecker.cpp153
-rw-r--r--libraries/logic/status/StatusChecker.h60
-rw-r--r--libraries/logic/tasks/SequentialTask.cpp55
-rw-r--r--libraries/logic/tasks/SequentialTask.h31
-rw-r--r--libraries/logic/tasks/Task.cpp88
-rw-r--r--libraries/logic/tasks/Task.h96
-rw-r--r--libraries/logic/tasks/ThreadTask.cpp41
-rw-r--r--libraries/logic/tasks/ThreadTask.h25
-rw-r--r--libraries/logic/tools/BaseExternalTool.cpp41
-rw-r--r--libraries/logic/tools/BaseExternalTool.h60
-rw-r--r--libraries/logic/tools/BaseProfiler.cpp35
-rw-r--r--libraries/logic/tools/BaseProfiler.h38
-rw-r--r--libraries/logic/tools/JProfiler.cpp116
-rw-r--r--libraries/logic/tools/JProfiler.h15
-rw-r--r--libraries/logic/tools/JVisualVM.cpp103
-rw-r--r--libraries/logic/tools/JVisualVM.h15
-rw-r--r--libraries/logic/tools/MCEditTool.cpp124
-rw-r--r--libraries/logic/tools/MCEditTool.h26
-rw-r--r--libraries/logic/trans/TranslationDownloader.cpp53
-rw-r--r--libraries/logic/trans/TranslationDownloader.h32
-rw-r--r--libraries/logic/updater/DownloadTask.cpp169
-rw-r--r--libraries/logic/updater/DownloadTask.h95
-rw-r--r--libraries/logic/updater/GoUpdate.cpp216
-rw-r--r--libraries/logic/updater/GoUpdate.h133
-rw-r--r--libraries/logic/updater/UpdateChecker.cpp269
-rw-r--r--libraries/logic/updater/UpdateChecker.h121
-rw-r--r--libraries/logic/wonko/BaseWonkoEntity.cpp39
-rw-r--r--libraries/logic/wonko/BaseWonkoEntity.h51
-rw-r--r--libraries/logic/wonko/WonkoIndex.cpp147
-rw-r--r--libraries/logic/wonko/WonkoIndex.h68
-rw-r--r--libraries/logic/wonko/WonkoReference.cpp44
-rw-r--r--libraries/logic/wonko/WonkoReference.h41
-rw-r--r--libraries/logic/wonko/WonkoUtil.cpp47
-rw-r--r--libraries/logic/wonko/WonkoUtil.h31
-rw-r--r--libraries/logic/wonko/WonkoVersion.cpp102
-rw-r--r--libraries/logic/wonko/WonkoVersion.h83
-rw-r--r--libraries/logic/wonko/WonkoVersionList.cpp283
-rw-r--r--libraries/logic/wonko/WonkoVersionList.h92
-rw-r--r--libraries/logic/wonko/format/WonkoFormat.cpp80
-rw-r--r--libraries/logic/wonko/format/WonkoFormat.h54
-rw-r--r--libraries/logic/wonko/format/WonkoFormatV1.cpp156
-rw-r--r--libraries/logic/wonko/format/WonkoFormatV1.h30
-rw-r--r--libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.cpp117
-rw-r--r--libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.h81
-rw-r--r--libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.cpp126
-rw-r--r--libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.h85
260 files changed, 0 insertions, 32792 deletions
diff --git a/libraries/logic/AbstractCommonModel.cpp b/libraries/logic/AbstractCommonModel.cpp
deleted file mode 100644
index 71d75829..00000000
--- a/libraries/logic/AbstractCommonModel.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright 2015 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 "AbstractCommonModel.h"
-
-BaseAbstractCommonModel::BaseAbstractCommonModel(const Qt::Orientation orientation, QObject *parent)
- : QAbstractListModel(parent), m_orientation(orientation)
-{
-}
-
-int BaseAbstractCommonModel::rowCount(const QModelIndex &parent) const
-{
- return m_orientation == Qt::Horizontal ? entryCount() : size();
-}
-int BaseAbstractCommonModel::columnCount(const QModelIndex &parent) const
-{
- return m_orientation == Qt::Horizontal ? size() : entryCount();
-}
-QVariant BaseAbstractCommonModel::data(const QModelIndex &index, int role) const
-{
- if (!hasIndex(index.row(), index.column(), index.parent()))
- {
- return QVariant();
- }
- const int i = m_orientation == Qt::Horizontal ? index.column() : index.row();
- const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column();
- return formatData(i, role, get(i, entry, role));
-}
-QVariant BaseAbstractCommonModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation != m_orientation && role == Qt::DisplayRole)
- {
- return entryTitle(section);
- }
- else
- {
- return QVariant();
- }
-}
-bool BaseAbstractCommonModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- const int i = m_orientation == Qt::Horizontal ? index.column() : index.row();
- const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column();
- const bool result = set(i, entry, role, sanetizeData(i, role, value));
- if (result)
- {
- emit dataChanged(index, index, QVector<int>() << role);
- }
- return result;
-}
-Qt::ItemFlags BaseAbstractCommonModel::flags(const QModelIndex &index) const
-{
- if (!hasIndex(index.row(), index.column(), index.parent()))
- {
- return Qt::NoItemFlags;
- }
-
- const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column();
- if (canSet(entry))
- {
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
- }
- else
- {
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
- }
-}
-
-void BaseAbstractCommonModel::notifyAboutToAddObject(const int at)
-{
- if (m_orientation == Qt::Horizontal)
- {
- beginInsertColumns(QModelIndex(), at, at);
- }
- else
- {
- beginInsertRows(QModelIndex(), at, at);
- }
-}
-void BaseAbstractCommonModel::notifyObjectAdded()
-{
- if (m_orientation == Qt::Horizontal)
- {
- endInsertColumns();
- }
- else
- {
- endInsertRows();
- }
-}
-void BaseAbstractCommonModel::notifyAboutToRemoveObject(const int at)
-{
- if (m_orientation == Qt::Horizontal)
- {
- beginRemoveColumns(QModelIndex(), at, at);
- }
- else
- {
- beginRemoveRows(QModelIndex(), at, at);
- }
-}
-void BaseAbstractCommonModel::notifyObjectRemoved()
-{
- if (m_orientation == Qt::Horizontal)
- {
- endRemoveColumns();
- }
- else
- {
- endRemoveRows();
- }
-}
-
-void BaseAbstractCommonModel::notifyBeginReset()
-{
- beginResetModel();
-}
-void BaseAbstractCommonModel::notifyEndReset()
-{
- endResetModel();
-}
diff --git a/libraries/logic/AbstractCommonModel.h b/libraries/logic/AbstractCommonModel.h
deleted file mode 100644
index 31b86a23..00000000
--- a/libraries/logic/AbstractCommonModel.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QAbstractListModel>
-#include <type_traits>
-#include <functional>
-#include <memory>
-
-class BaseAbstractCommonModel : public QAbstractListModel
-{
- Q_OBJECT
-public:
- explicit BaseAbstractCommonModel(const Qt::Orientation orientation, QObject *parent = nullptr);
-
- // begin QAbstractItemModel interface
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- bool setData(const QModelIndex &index, const QVariant &value, int role) override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
- // end QAbstractItemModel interface
-
- virtual int size() const = 0;
- virtual int entryCount() const = 0;
-
- virtual QVariant formatData(const int index, int role, const QVariant &data) const { return data; }
- virtual QVariant sanetizeData(const int index, int role, const QVariant &data) const { return data; }
-
-protected:
- virtual QVariant get(const int index, const int entry, const int role) const = 0;
- virtual bool set(const int index, const int entry, const int role, const QVariant &value) = 0;
- virtual bool canSet(const int entry) const = 0;
- virtual QString entryTitle(const int entry) const = 0;
-
- void notifyAboutToAddObject(const int at);
- void notifyObjectAdded();
- void notifyAboutToRemoveObject(const int at);
- void notifyObjectRemoved();
- void notifyBeginReset();
- void notifyEndReset();
-
- const Qt::Orientation m_orientation;
-};
-
-template<typename Object>
-class AbstractCommonModel : public BaseAbstractCommonModel
-{
-public:
- explicit AbstractCommonModel(const Qt::Orientation orientation)
- : BaseAbstractCommonModel(orientation) {}
- virtual ~AbstractCommonModel() {}
-
- int size() const override { return m_objects.size(); }
- int entryCount() const override { return m_entries.size(); }
-
- void append(const Object &object)
- {
- notifyAboutToAddObject(size());
- m_objects.append(object);
- notifyObjectAdded();
- }
- void prepend(const Object &object)
- {
- notifyAboutToAddObject(0);
- m_objects.prepend(object);
- notifyObjectAdded();
- }
- void insert(const Object &object, const int index)
- {
- if (index >= size())
- {
- prepend(object);
- }
- else if (index <= 0)
- {
- append(object);
- }
- else
- {
- notifyAboutToAddObject(index);
- m_objects.insert(index, object);
- notifyObjectAdded();
- }
- }
- void remove(const int index)
- {
- notifyAboutToRemoveObject(index);
- m_objects.removeAt(index);
- notifyObjectRemoved();
- }
- Object get(const int index) const
- {
- return m_objects.at(index);
- }
-
-private:
- friend class CommonModel;
- QVariant get(const int index, const int entry, const int role) const override
- {
- if (m_entries.size() < entry || !m_entries[entry].second.contains(role))
- {
- return QVariant();
- }
- return m_entries[entry].second.value(role)->get(m_objects.at(index));
- }
- bool set(const int index, const int entry, const int role, const QVariant &value) override
- {
- if (m_entries.size() < entry || !m_entries[entry].second.contains(role))
- {
- return false;
- }
- IEntry *e = m_entries[entry].second.value(role);
- if (!e->canSet())
- {
- return false;
- }
- e->set(m_objects[index], value);
- return true;
- }
- bool canSet(const int entry) const override
- {
- if (m_entries.size() < entry || !m_entries[entry].second.contains(Qt::EditRole))
- {
- return false;
- }
- IEntry *e = m_entries[entry].second.value(Qt::EditRole);
- return e->canSet();
- }
-
- QString entryTitle(const int entry) const override
- {
- return m_entries.at(entry).first;
- }
-
-private:
- struct IEntry
- {
- virtual ~IEntry() {}
- virtual void set(Object &object, const QVariant &value) = 0;
- virtual QVariant get(const Object &object) const = 0;
- virtual bool canSet() const = 0;
- };
- template<typename T>
- struct VariableEntry : public IEntry
- {
- typedef T (Object::*Member);
-
- explicit VariableEntry(Member member)
- : m_member(member) {}
-
- void set(Object &object, const QVariant &value) override
- {
- object.*m_member = value.value<T>();
- }
- QVariant get(const Object &object) const override
- {
- return QVariant::fromValue<T>(object.*m_member);
- }
- bool canSet() const override { return true; }
-
- private:
- Member m_member;
- };
- template<typename T>
- struct FunctionEntry : public IEntry
- {
- typedef T (Object::*Getter)() const;
- typedef void (Object::*Setter)(T);
-
- explicit FunctionEntry(Getter getter, Setter setter)
- : m_getter(m_getter), m_setter(m_setter) {}
-
- void set(Object &object, const QVariant &value) override
- {
- object.*m_setter(value.value<T>());
- }
- QVariant get(const Object &object) const override
- {
- return QVariant::fromValue<T>(object.*m_getter());
- }
- bool canSet() const override { return !!m_setter; }
-
- private:
- Getter m_getter;
- Setter m_setter;
- };
-
- QList<Object> m_objects;
- QVector<QPair<QString, QMap<int, IEntry *>>> m_entries;
-
- void addEntryInternal(IEntry *e, const int entry, const int role)
- {
- if (m_entries.size() <= entry)
- {
- m_entries.resize(entry + 1);
- }
- m_entries[entry].second.insert(role, e);
- }
-
-protected:
- template<typename Getter, typename Setter>
- typename std::enable_if<std::is_member_function_pointer<Getter>::value && std::is_member_function_pointer<Getter>::value, void>::type
- addEntry(Getter getter, Setter setter, const int entry, const int role)
- {
- addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, setter), entry, role);
- }
- template<typename Getter>
- typename std::enable_if<std::is_member_function_pointer<Getter>::value, void>::type
- addEntry(Getter getter, const int entry, const int role)
- {
- addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, nullptr), entry, role);
- }
- template<typename T>
- typename std::enable_if<!std::is_member_function_pointer<T (Object::*)>::value, void>::type
- addEntry(T (Object::*member), const int entry, const int role)
- {
- addEntryInternal(new VariableEntry<T>(member), entry, role);
- }
-
- void setEntryTitle(const int entry, const QString &title)
- {
- m_entries[entry].first = title;
- }
-};
-template<typename Object>
-class AbstractCommonModel<Object *> : public BaseAbstractCommonModel
-{
-public:
- explicit AbstractCommonModel(const Qt::Orientation orientation)
- : BaseAbstractCommonModel(orientation) {}
- virtual ~AbstractCommonModel()
- {
- qDeleteAll(m_objects);
- }
-
- int size() const override { return m_objects.size(); }
- int entryCount() const override { return m_entries.size(); }
-
- void append(Object *object)
- {
- notifyAboutToAddObject(size());
- m_objects.append(object);
- notifyObjectAdded();
- }
- void prepend(Object *object)
- {
- notifyAboutToAddObject(0);
- m_objects.prepend(object);
- notifyObjectAdded();
- }
- void insert(Object *object, const int index)
- {
- if (index >= size())
- {
- prepend(object);
- }
- else if (index <= 0)
- {
- append(object);
- }
- else
- {
- notifyAboutToAddObject(index);
- m_objects.insert(index, object);
- notifyObjectAdded();
- }
- }
- void remove(const int index)
- {
- notifyAboutToRemoveObject(index);
- m_objects.removeAt(index);
- notifyObjectRemoved();
- }
- Object *get(const int index) const
- {
- return m_objects.at(index);
- }
- int find(Object * const obj) const
- {
- return m_objects.indexOf(obj);
- }
-
- QList<Object *> getAll() const
- {
- return m_objects;
- }
-
-private:
- friend class CommonModel;
- QVariant get(const int index, const int entry, const int role) const override
- {
- if (m_entries.size() < entry || !m_entries[entry].second.contains(role))
- {
- return QVariant();
- }
- return m_entries[entry].second.value(role)->get(m_objects.at(index));
- }
- bool set(const int index, const int entry, const int role, const QVariant &value) override
- {
- if (m_entries.size() < entry || !m_entries[entry].second.contains(role))
- {
- return false;
- }
- IEntry *e = m_entries[entry].second.value(role);
- if (!e->canSet())
- {
- return false;
- }
- e->set(m_objects[index], value);
- return true;
- }
- bool canSet(const int entry) const override
- {
- if (m_entries.size() < entry || !m_entries[entry].second.contains(Qt::EditRole))
- {
- return false;
- }
- IEntry *e = m_entries[entry].second.value(Qt::EditRole);
- return e->canSet();
- }
-
- QString entryTitle(const int entry) const override
- {
- return m_entries.at(entry).first;
- }
-
-private:
- struct IEntry
- {
- virtual ~IEntry() {}
- virtual void set(Object *object, const QVariant &value) = 0;
- virtual QVariant get(Object *object) const = 0;
- virtual bool canSet() const = 0;
- };
- template<typename T>
- struct VariableEntry : public IEntry
- {
- typedef T (Object::*Member);
-
- explicit VariableEntry(Member member)
- : m_member(member) {}
-
- void set(Object *object, const QVariant &value) override
- {
- object->*m_member = value.value<T>();
- }
- QVariant get(Object *object) const override
- {
- return QVariant::fromValue<T>(object->*m_member);
- }
- bool canSet() const override { return true; }
-
- private:
- Member m_member;
- };
- template<typename T>
- struct FunctionEntry : public IEntry
- {
- typedef T (Object::*Getter)() const;
- typedef void (Object::*Setter)(T);
-
- explicit FunctionEntry(Getter getter, Setter setter)
- : m_getter(getter), m_setter(setter) {}
-
- void set(Object *object, const QVariant &value) override
- {
- (object->*m_setter)(value.value<T>());
- }
- QVariant get(Object *object) const override
- {
- return QVariant::fromValue<T>((object->*m_getter)());
- }
- bool canSet() const override { return !!m_setter; }
-
- private:
- Getter m_getter;
- Setter m_setter;
- };
- template<typename T>
- struct LambdaEntry : public IEntry
- {
- using Getter = std::function<T(Object *)>;
-
- explicit LambdaEntry(Getter getter)
- : m_getter(getter) {}
-
- void set(Object *object, const QVariant &value) override {}
- QVariant get(Object *object) const override
- {
- return QVariant::fromValue<T>(m_getter(object));
- }
- bool canSet() const override { return false; }
-
- private:
- Getter m_getter;
- };
-
- QList<Object *> m_objects;
- QVector<QPair<QString, QMap<int, IEntry *>>> m_entries;
-
- void addEntryInternal(IEntry *e, const int entry, const int role)
- {
- if (m_entries.size() <= entry)
- {
- m_entries.resize(entry + 1);
- }
- m_entries[entry].second.insert(role, e);
- }
-
-protected:
- template<typename Getter, typename Setter>
- typename std::enable_if<std::is_member_function_pointer<Getter>::value && std::is_member_function_pointer<Getter>::value, void>::type
- addEntry(const int entry, const int role, Getter getter, Setter setter)
- {
- addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, setter), entry, role);
- }
- template<typename T>
- typename std::enable_if<std::is_member_function_pointer<typename FunctionEntry<T>::Getter>::value, void>::type
- addEntry(const int entry, const int role, typename FunctionEntry<T>::Getter getter)
- {
- addEntryInternal(new FunctionEntry<T>(getter, nullptr), entry, role);
- }
- template<typename T>
- typename std::enable_if<!std::is_member_function_pointer<T (Object::*)>::value, void>::type
- addEntry(const int entry, const int role, T (Object::*member))
- {
- addEntryInternal(new VariableEntry<T>(member), entry, role);
- }
- template<typename T>
- void addEntry(const int entry, const int role, typename LambdaEntry<T>::Getter lambda)
- {
- addEntryInternal(new LambdaEntry<T>(lambda), entry, role);
- }
-
- void setEntryTitle(const int entry, const QString &title)
- {
- m_entries[entry].first = title;
- }
-
- void setAll(const QList<Object *> objects)
- {
- notifyBeginReset();
- qDeleteAll(m_objects);
- m_objects = objects;
- notifyEndReset();
- }
-};
diff --git a/libraries/logic/BaseConfigObject.cpp b/libraries/logic/BaseConfigObject.cpp
deleted file mode 100644
index 3040ac2e..00000000
--- a/libraries/logic/BaseConfigObject.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright 2015 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 "BaseConfigObject.h"
-
-#include <QTimer>
-#include <QFile>
-#include <QCoreApplication>
-#include <QDebug>
-
-#include "Exception.h"
-#include "FileSystem.h"
-
-BaseConfigObject::BaseConfigObject(const QString &filename)
- : m_filename(filename)
-{
- m_saveTimer = new QTimer;
- m_saveTimer->setSingleShot(true);
- // cppcheck-suppress pureVirtualCall
- QObject::connect(m_saveTimer, &QTimer::timeout, [this](){saveNow();});
- setSaveTimeout(250);
-
- m_initialReadTimer = new QTimer;
- m_initialReadTimer->setSingleShot(true);
- QObject::connect(m_initialReadTimer, &QTimer::timeout, [this]()
- {
- loadNow();
- m_initialReadTimer->deleteLater();
- m_initialReadTimer = 0;
- });
- m_initialReadTimer->start(0);
-
- // cppcheck-suppress pureVirtualCall
- m_appQuitConnection = QObject::connect(qApp, &QCoreApplication::aboutToQuit, [this](){saveNow();});
-}
-BaseConfigObject::~BaseConfigObject()
-{
- delete m_saveTimer;
- if (m_initialReadTimer)
- {
- delete m_initialReadTimer;
- }
- QObject::disconnect(m_appQuitConnection);
-}
-
-void BaseConfigObject::setSaveTimeout(int msec)
-{
- m_saveTimer->setInterval(msec);
-}
-
-void BaseConfigObject::scheduleSave()
-{
- m_saveTimer->stop();
- m_saveTimer->start();
-}
-void BaseConfigObject::saveNow()
-{
- if (m_saveTimer->isActive())
- {
- m_saveTimer->stop();
- }
- if (m_disableSaving)
- {
- return;
- }
-
- try
- {
- FS::write(m_filename, doSave());
- }
- catch (Exception & e)
- {
- qCritical() << e.cause();
- }
-}
-void BaseConfigObject::loadNow()
-{
- if (m_saveTimer->isActive())
- {
- saveNow();
- }
-
- try
- {
- doLoad(FS::read(m_filename));
- }
- catch (Exception & e)
- {
- qWarning() << "Error loading" << m_filename << ":" << e.cause();
- }
-}
diff --git a/libraries/logic/BaseConfigObject.h b/libraries/logic/BaseConfigObject.h
deleted file mode 100644
index 1c96b3d1..00000000
--- a/libraries/logic/BaseConfigObject.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-
-class QTimer;
-
-class BaseConfigObject
-{
-public:
- void setSaveTimeout(int msec);
-
-protected:
- explicit BaseConfigObject(const QString &filename);
- virtual ~BaseConfigObject();
-
- // cppcheck-suppress pureVirtualCall
- virtual QByteArray doSave() const = 0;
- virtual void doLoad(const QByteArray &data) = 0;
-
- void setSavingDisabled(bool savingDisabled) { m_disableSaving = savingDisabled; }
-
- QString fileName() const { return m_filename; }
-
-public:
- void scheduleSave();
- void saveNow();
- void loadNow();
-
-private:
- QTimer *m_saveTimer;
- QTimer *m_initialReadTimer;
- QString m_filename;
- QMetaObject::Connection m_appQuitConnection;
- bool m_disableSaving = false;
-};
diff --git a/libraries/logic/BaseInstaller.cpp b/libraries/logic/BaseInstaller.cpp
deleted file mode 100644
index cb762ebd..00000000
--- a/libraries/logic/BaseInstaller.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright 2013-2015 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 <QFile>
-
-#include "BaseInstaller.h"
-#include "minecraft/onesix/OneSixInstance.h"
-
-BaseInstaller::BaseInstaller()
-{
-
-}
-
-bool BaseInstaller::isApplied(OneSixInstance *on)
-{
- return QFile::exists(filename(on->instanceRoot()));
-}
-
-bool BaseInstaller::add(OneSixInstance *to)
-{
- if (!patchesDir(to->instanceRoot()).exists())
- {
- QDir(to->instanceRoot()).mkdir("patches");
- }
-
- if (isApplied(to))
- {
- if (!remove(to))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool BaseInstaller::remove(OneSixInstance *from)
-{
- return QFile::remove(filename(from->instanceRoot()));
-}
-
-QString BaseInstaller::filename(const QString &root) const
-{
- return patchesDir(root).absoluteFilePath(id() + ".json");
-}
-QDir BaseInstaller::patchesDir(const QString &root) const
-{
- return QDir(root + "/patches/");
-}
diff --git a/libraries/logic/BaseInstaller.h b/libraries/logic/BaseInstaller.h
deleted file mode 100644
index a50c8cb1..00000000
--- a/libraries/logic/BaseInstaller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class OneSixInstance;
-class QDir;
-class QString;
-class QObject;
-class Task;
-class BaseVersion;
-typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
-
-class MULTIMC_LOGIC_EXPORT BaseInstaller
-{
-public:
- BaseInstaller();
- virtual ~BaseInstaller(){};
- bool isApplied(OneSixInstance *on);
-
- virtual bool add(OneSixInstance *to);
- virtual bool remove(OneSixInstance *from);
-
- virtual Task *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) = 0;
-
-protected:
- virtual QString id() const = 0;
- QString filename(const QString &root) const;
- QDir patchesDir(const QString &root) const;
-};
diff --git a/libraries/logic/BaseInstance.cpp b/libraries/logic/BaseInstance.cpp
deleted file mode 100644
index ce55d5e4..00000000
--- a/libraries/logic/BaseInstance.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/* Copyright 2013-2015 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 "BaseInstance.h"
-
-#include <QFileInfo>
-#include <QDir>
-
-#include "settings/INISettingsObject.h"
-#include "settings/Setting.h"
-#include "settings/OverrideSetting.h"
-
-#include "minecraft/MinecraftVersionList.h"
-#include "FileSystem.h"
-#include "Commandline.h"
-
-BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : QObject()
-{
- m_settings = settings;
- m_rootDir = rootDir;
-
- m_settings->registerSetting("name", "Unnamed Instance");
- m_settings->registerSetting("iconKey", "default");
- m_settings->registerSetting("notes", "");
- m_settings->registerSetting("lastLaunchTime", 0);
- m_settings->registerSetting("totalTimePlayed", 0);
-
- // Custom Commands
- auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false);
- m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand"), commandSetting);
- m_settings->registerOverride(globalSettings->getSetting("WrapperCommand"), commandSetting);
- m_settings->registerOverride(globalSettings->getSetting("PostExitCommand"), commandSetting);
-
- // Console
- auto consoleSetting = m_settings->registerSetting("OverrideConsole", false);
- m_settings->registerOverride(globalSettings->getSetting("ShowConsole"), consoleSetting);
- m_settings->registerOverride(globalSettings->getSetting("AutoCloseConsole"), consoleSetting);
- m_settings->registerOverride(globalSettings->getSetting("LogPrePostOutput"), consoleSetting);
-}
-
-QString BaseInstance::getPreLaunchCommand()
-{
- return settings()->get("PreLaunchCommand").toString();
-}
-
-QString BaseInstance::getWrapperCommand()
-{
- return settings()->get("WrapperCommand").toString();
-}
-
-QString BaseInstance::getPostExitCommand()
-{
- return settings()->get("PostExitCommand").toString();
-}
-
-void BaseInstance::iconUpdated(QString key)
-{
- if(iconKey() == key)
- {
- emit propertiesChanged(this);
- }
-}
-
-void BaseInstance::nuke()
-{
- FS::deletePath(instanceRoot());
- emit nuked(this);
-}
-
-QString BaseInstance::id() const
-{
- return QFileInfo(instanceRoot()).fileName();
-}
-
-bool BaseInstance::isRunning() const
-{
- return m_isRunning;
-}
-
-void BaseInstance::setRunning(bool running)
-{
- if(running && !m_isRunning)
- {
- m_timeStarted = QDateTime::currentDateTime();
- }
- else if(!running && m_isRunning)
- {
- qint64 current = settings()->get("totalTimePlayed").toLongLong();
- QDateTime timeEnded = QDateTime::currentDateTime();
- settings()->set("totalTimePlayed", current + m_timeStarted.secsTo(timeEnded));
- emit propertiesChanged(this);
- }
- m_isRunning = running;
-}
-
-int64_t BaseInstance::totalTimePlayed() const
-{
- qint64 current = settings()->get("totalTimePlayed").toLongLong();
- if(m_isRunning)
- {
- QDateTime timeNow = QDateTime::currentDateTime();
- return current + m_timeStarted.secsTo(timeNow);
- }
- return current;
-}
-
-void BaseInstance::resetTimePlayed()
-{
- settings()->reset("totalTimePlayed");
-}
-
-QString BaseInstance::instanceType() const
-{
- return m_settings->get("InstanceType").toString();
-}
-
-QString BaseInstance::instanceRoot() const
-{
- return m_rootDir;
-}
-
-InstancePtr BaseInstance::getSharedPtr()
-{
- return shared_from_this();
-}
-
-SettingsObjectPtr BaseInstance::settings() const
-{
- return m_settings;
-}
-
-BaseInstance::InstanceFlags BaseInstance::flags() const
-{
- return m_flags;
-}
-
-void BaseInstance::setFlags(const InstanceFlags &flags)
-{
- if (flags != m_flags)
- {
- m_flags = flags;
- emit flagsChanged();
- emit propertiesChanged(this);
- }
-}
-
-void BaseInstance::setFlag(const BaseInstance::InstanceFlag flag)
-{
- // nothing to set?
- if(flag & m_flags)
- return;
- m_flags |= flag;
- emit flagsChanged();
- emit propertiesChanged(this);
-}
-
-void BaseInstance::unsetFlag(const BaseInstance::InstanceFlag flag)
-{
- // nothing to unset?
- if(!(flag & m_flags))
- return;
- m_flags &= ~flag;
- emit flagsChanged();
- emit propertiesChanged(this);
-}
-
-bool BaseInstance::canLaunch() const
-{
- return !(flags() & VersionBrokenFlag);
-}
-
-bool BaseInstance::reload()
-{
- return m_settings->reload();
-}
-
-qint64 BaseInstance::lastLaunch() const
-{
- return m_settings->get("lastLaunchTime").value<qint64>();
-}
-
-void BaseInstance::setLastLaunch(qint64 val)
-{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("lastLaunchTime", val);
- emit propertiesChanged(this);
-}
-
-void BaseInstance::setGroupInitial(QString val)
-{
- if(m_group == val)
- {
- return;
- }
- m_group = val;
- emit propertiesChanged(this);
-}
-
-void BaseInstance::setGroupPost(QString val)
-{
- if(m_group == val)
- {
- return;
- }
- setGroupInitial(val);
- emit groupChanged();
-}
-
-QString BaseInstance::group() const
-{
- return m_group;
-}
-
-void BaseInstance::setNotes(QString val)
-{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("notes", val);
-}
-
-QString BaseInstance::notes() const
-{
- return m_settings->get("notes").toString();
-}
-
-void BaseInstance::setIconKey(QString val)
-{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("iconKey", val);
- emit propertiesChanged(this);
-}
-
-QString BaseInstance::iconKey() const
-{
- return m_settings->get("iconKey").toString();
-}
-
-void BaseInstance::setName(QString val)
-{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("name", val);
- emit propertiesChanged(this);
-}
-
-QString BaseInstance::name() const
-{
- return m_settings->get("name").toString();
-}
-
-QString BaseInstance::windowTitle() const
-{
- return "MultiMC: " + name();
-}
-
-QStringList BaseInstance::extraArguments() const
-{
- return Commandline::splitArgs(settings()->get("JvmArgs").toString());
-}
diff --git a/libraries/logic/BaseInstance.h b/libraries/logic/BaseInstance.h
deleted file mode 100644
index 5e587c48..00000000
--- a/libraries/logic/BaseInstance.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QDateTime>
-#include <QSet>
-#include <QProcess>
-
-#include "settings/SettingsObject.h"
-
-#include "settings/INIFile.h"
-#include "BaseVersionList.h"
-#include "minecraft/auth/MojangAccount.h"
-#include "launch/MessageLevel.h"
-#include "pathmatcher/IPathMatcher.h"
-
-#include "multimc_logic_export.h"
-
-class QDir;
-class Task;
-class LaunchTask;
-class BaseInstance;
-
-// pointer for lazy people
-typedef std::shared_ptr<BaseInstance> InstancePtr;
-
-/*!
- * \brief Base class for instances.
- * This class implements many functions that are common between instances and
- * provides a standard interface for all instances.
- *
- * To create a new instance type, create a new class inheriting from this class
- * and implement the pure virtual functions.
- */
-class MULTIMC_LOGIC_EXPORT BaseInstance : public QObject, public std::enable_shared_from_this<BaseInstance>
-{
- Q_OBJECT
-protected:
- /// no-touchy!
- BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
-
-public:
- /// virtual destructor to make sure the destruction is COMPLETE
- virtual ~BaseInstance() {};
-
- virtual void copy(const QDir &newDir) {}
-
- virtual void init() = 0;
-
- /// nuke thoroughly - deletes the instance contents, notifies the list/model which is
- /// responsible of cleaning up the husk
- void nuke();
-
- /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to
- /// be unique.
- virtual QString id() const;
-
- void setRunning(bool running);
- bool isRunning() const;
- int64_t totalTimePlayed() const;
- void resetTimePlayed();
-
- /// get the type of this instance
- QString instanceType() const;
-
- /// Path to the instance's root directory.
- QString instanceRoot() const;
-
- QString name() const;
- void setName(QString val);
-
- /// Value used for instance window titles
- QString windowTitle() const;
-
- QString iconKey() const;
- void setIconKey(QString val);
-
- QString notes() const;
- void setNotes(QString val);
-
- QString group() const;
- void setGroupInitial(QString val);
- void setGroupPost(QString val);
-
- QString getPreLaunchCommand();
- QString getPostExitCommand();
- QString getWrapperCommand();
-
- /// guess log level from a line of game log
- virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level)
- {
- return level;
- };
-
- virtual QStringList extraArguments() const;
-
- virtual QString intendedVersionId() const = 0;
- virtual bool setIntendedVersionId(QString version) = 0;
-
- /*!
- * The instance's current version.
- * This value represents the instance's current version. If this value is
- * different from the intendedVersion, the instance should be updated.
- * \warning Don't change this value unless you know what you're doing.
- */
- virtual QString currentVersionId() const = 0;
-
- /*!
- * Whether or not 'the game' should be downloaded when the instance is launched.
- */
- virtual bool shouldUpdate() const = 0;
- virtual void setShouldUpdate(bool val) = 0;
-
- /// Traits. Normally inside the version, depends on instance implementation.
- virtual QSet <QString> traits() = 0;
-
- /**
- * Gets the time that the instance was last launched.
- * Stored in milliseconds since epoch.
- */
- qint64 lastLaunch() const;
- /// Sets the last launched time to 'val' milliseconds since epoch
- void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch());
-
- InstancePtr getSharedPtr();
-
- /*!
- * \brief Gets a pointer to this instance's version list.
- * \return A pointer to the available version list for this instance.
- */
- virtual std::shared_ptr<BaseVersionList> versionList() const = 0;
-
- /*!
- * \brief Gets this instance's settings object.
- * This settings object stores instance-specific settings.
- * \return A pointer to this instance's settings object.
- */
- virtual SettingsObjectPtr settings() const;
-
- /// returns a valid update task
- virtual std::shared_ptr<Task> createUpdateTask() = 0;
-
- /// returns a valid launcher (task container)
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0;
-
- /*!
- * Returns a task that should be done right before launch
- * This task should do any extra preparations needed
- */
- virtual std::shared_ptr<Task> createJarModdingTask() = 0;
-
- /*!
- * Create envrironment variables for running the instance
- */
- virtual QProcessEnvironment createEnvironment() = 0;
-
- /*!
- * Returns a matcher that can maps relative paths within the instance to whether they are 'log files'
- */
- virtual IPathMatcher::Ptr getLogFileMatcher() = 0;
-
- /*!
- * Returns the root folder to use for looking up log files
- */
- virtual QString getLogFileRoot() = 0;
-
- /*!
- * does any necessary cleanups after the instance finishes. also runs before\
- * TODO: turn into a task that can run asynchronously
- */
- virtual void cleanupAfterRun() = 0;
-
- virtual QString getStatusbarDescription() = 0;
-
- /// FIXME: this really should be elsewhere...
- virtual QString instanceConfigFolder() const = 0;
-
- /// get variables this instance exports
- virtual QMap<QString, QString> getVariables() const = 0;
-
- virtual QString typeName() const = 0;
-
- enum InstanceFlag
- {
- VersionBrokenFlag = 0x01,
- UpdateAvailable = 0x02
- };
- Q_DECLARE_FLAGS(InstanceFlags, InstanceFlag)
- InstanceFlags flags() const;
- void setFlags(const InstanceFlags &flags);
- void setFlag(const InstanceFlag flag);
- void unsetFlag(const InstanceFlag flag);
-
- bool canLaunch() const;
- virtual bool canExport() const = 0;
-
- virtual bool reload();
-
-signals:
- /*!
- * \brief Signal emitted when properties relevant to the instance view change
- */
- void propertiesChanged(BaseInstance *inst);
- /*!
- * \brief Signal emitted when groups are affected in any way
- */
- void groupChanged();
- /*!
- * \brief The instance just got nuked. Hurray!
- */
- void nuked(BaseInstance *inst);
-
- void flagsChanged();
-
-protected slots:
- void iconUpdated(QString key);
-
-protected:
- QString m_rootDir;
- QString m_group;
- SettingsObjectPtr m_settings;
- InstanceFlags m_flags;
- bool m_isRunning = false;
- QDateTime m_timeStarted;
-};
-
-Q_DECLARE_METATYPE(std::shared_ptr<BaseInstance>)
-Q_DECLARE_METATYPE(BaseInstance::InstanceFlag)
-Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags)
diff --git a/libraries/logic/BaseVersion.h b/libraries/logic/BaseVersion.h
deleted file mode 100644
index 80767518..00000000
--- a/libraries/logic/BaseVersion.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <memory>
-#include <QString>
-#include <QMetaType>
-
-/*!
- * An abstract base class for versions.
- */
-class BaseVersion
-{
-public:
- virtual ~BaseVersion() {}
- /*!
- * A string used to identify this version in config files.
- * This should be unique within the version list or shenanigans will occur.
- */
- virtual QString descriptor() = 0;
-
- /*!
- * The name of this version as it is displayed to the user.
- * For example: "1.5.1"
- */
- virtual QString name() = 0;
-
- /*!
- * This should return a string that describes
- * the kind of version this is (Stable, Beta, Snapshot, whatever)
- */
- virtual QString typeString() const = 0;
-
- virtual bool operator<(BaseVersion &a)
- {
- return name() < a.name();
- };
- virtual bool operator>(BaseVersion &a)
- {
- return name() > a.name();
- };
-};
-
-typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
-
-Q_DECLARE_METATYPE(BaseVersionPtr)
diff --git a/libraries/logic/BaseVersionList.cpp b/libraries/logic/BaseVersionList.cpp
deleted file mode 100644
index b34f318c..00000000
--- a/libraries/logic/BaseVersionList.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright 2013-2015 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 "BaseVersionList.h"
-#include "BaseVersion.h"
-
-BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-BaseVersionPtr BaseVersionList::findVersion(const QString &descriptor)
-{
- for (int i = 0; i < count(); i++)
- {
- if (at(i)->descriptor() == descriptor)
- return at(i);
- }
- return BaseVersionPtr();
-}
-
-BaseVersionPtr BaseVersionList::getLatestStable() const
-{
- if (count() <= 0)
- return BaseVersionPtr();
- else
- return at(0);
-}
-
-BaseVersionPtr BaseVersionList::getRecommended() const
-{
- return getLatestStable();
-}
-
-QVariant BaseVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- BaseVersionPtr version = at(index.row());
-
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(version);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case TypeRole:
- return version->typeString();
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList BaseVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, TypeRole};
-}
-
-int BaseVersionList::rowCount(const QModelIndex &parent) const
-{
- // Return count
- return count();
-}
-
-int BaseVersionList::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QHash<int, QByteArray> BaseVersionList::roleNames() const
-{
- QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
- roles.insert(VersionRole, "version");
- roles.insert(VersionIdRole, "versionId");
- roles.insert(ParentGameVersionRole, "parentGameVersion");
- roles.insert(RecommendedRole, "recommended");
- roles.insert(LatestRole, "latest");
- roles.insert(TypeRole, "type");
- roles.insert(BranchRole, "branch");
- roles.insert(PathRole, "path");
- roles.insert(ArchitectureRole, "architecture");
- return roles;
-}
diff --git a/libraries/logic/BaseVersionList.h b/libraries/logic/BaseVersionList.h
deleted file mode 100644
index 73d2ee1f..00000000
--- a/libraries/logic/BaseVersionList.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QVariant>
-#include <QAbstractListModel>
-
-#include "BaseVersion.h"
-#include "tasks/Task.h"
-#include "multimc_logic_export.h"
-
-/*!
- * \brief Class that each instance type's version list derives from.
- * Version lists are the lists that keep track of the available game versions
- * for that instance. This list will not be loaded on startup. It will be loaded
- * when the list's load function is called. Before using the version list, you
- * should check to see if it has been loaded yet and if not, load the list.
- *
- * Note that this class also inherits from QAbstractListModel. Methods from that
- * class determine how this version list shows up in a list view. Said methods
- * all have a default implementation, but they can be overridden by plugins to
- * change the behavior of the list.
- */
-class MULTIMC_LOGIC_EXPORT BaseVersionList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum ModelRoles
- {
- VersionPointerRole = Qt::UserRole,
- VersionRole,
- VersionIdRole,
- ParentGameVersionRole,
- RecommendedRole,
- LatestRole,
- TypeRole,
- BranchRole,
- PathRole,
- ArchitectureRole,
- SortRole
- };
- typedef QList<int> RoleList;
-
- explicit BaseVersionList(QObject *parent = 0);
-
- /*!
- * \brief Gets a task that will reload the version list.
- * Simply execute the task to load the list.
- * The task returned by this function should reset the model when it's done.
- * \return A pointer to a task that reloads the version list.
- */
- virtual Task *getLoadTask() = 0;
-
- //! Checks whether or not the list is loaded. If this returns false, the list should be
- //loaded.
- virtual bool isLoaded() = 0;
-
- //! Gets the version at the given index.
- virtual const BaseVersionPtr at(int i) const = 0;
-
- //! Returns the number of versions in the list.
- virtual int count() const = 0;
-
- //////// List Model Functions ////////
- virtual QVariant data(const QModelIndex &index, int role) const;
- virtual int rowCount(const QModelIndex &parent) const;
- virtual int columnCount(const QModelIndex &parent) const;
- virtual QHash<int, QByteArray> roleNames() const override;
-
- //! which roles are provided by this version list?
- virtual RoleList providesRoles() const;
-
- /*!
- * \brief Finds a version by its descriptor.
- * \param The descriptor of the version to find.
- * \return A const pointer to the version with the given descriptor. NULL if
- * one doesn't exist.
- */
- virtual BaseVersionPtr findVersion(const QString &descriptor);
-
- /*!
- * \brief Gets the latest stable version from this list
- */
- virtual BaseVersionPtr getLatestStable() const;
-
- /*!
- * \brief Gets the recommended version from this list
- * If the list doesn't support recommended versions, this works exactly as getLatestStable
- */
- virtual BaseVersionPtr getRecommended() const;
-
- /*!
- * Sorts the version list.
- */
- virtual void sortVersions() = 0;
-
-protected
-slots:
- /*!
- * Updates this list with the given list of versions.
- * This is done by copying each version in the given list and inserting it
- * into this one.
- * We need to do this so that we can set the parents of the versions are set to this
- * version list. This can't be done in the load task, because the versions the load
- * task creates are on the load task's thread and Qt won't allow their parents
- * to be set to something created on another thread.
- * To get around that problem, we invoke this method on the GUI thread, which
- * then copies the versions and sets their parents correctly.
- * \param versions List of versions whose parents should be set.
- */
- virtual void updateListData(QList<BaseVersionPtr> versions) = 0;
-};
diff --git a/libraries/logic/CMakeLists.txt b/libraries/logic/CMakeLists.txt
deleted file mode 100644
index 317627d5..00000000
--- a/libraries/logic/CMakeLists.txt
+++ /dev/null
@@ -1,344 +0,0 @@
-project(MultiMC_logic)
-
-set(LOGIC_SOURCES
- # LOGIC - Base classes and infrastructure
- BaseInstaller.h
- BaseInstaller.cpp
- BaseVersionList.h
- BaseVersionList.cpp
- InstanceList.h
- InstanceList.cpp
- BaseVersion.h
- BaseInstance.h
- BaseInstance.cpp
- NullInstance.h
- MMCZip.h
- MMCZip.cpp
- MMCStrings.h
- MMCStrings.cpp
- BaseConfigObject.h
- BaseConfigObject.cpp
- AbstractCommonModel.h
- AbstractCommonModel.cpp
- TypeMagic.h
-
- # Prefix tree where node names are strings between separators
- SeparatorPrefixTree.h
-
- # WARNING: globals live here
- Env.h
- Env.cpp
-
- # JSON parsing helpers
- Json.h
- Json.cpp
-
- FileSystem.h
- FileSystem.cpp
-
- Exception.h
-
- # RW lock protected map
- RWStorage.h
-
- # A variable that has an implicit default value and keeps track of changes
- DefaultVariable.h
-
- # a smart pointer wrapper intended for safer use with Qt signal/slot mechanisms
- QObjectPtr.h
-
- # Resources
- resources/Resource.cpp
- resources/Resource.h
- resources/ResourceHandler.cpp
- resources/ResourceHandler.h
- resources/ResourceObserver.cpp
- resources/ResourceObserver.h
- resources/ResourceProxyModel.h
- resources/ResourceProxyModel.cpp
-
- # Path matchers
- pathmatcher/FSTreeMatcher.h
- pathmatcher/IPathMatcher.h
- pathmatcher/MultiMatcher.h
- pathmatcher/RegexpMatcher.h
-
- # Compression support
- GZip.h
- GZip.cpp
-
- # Command line parameter parsing
- Commandline.h
- Commandline.cpp
-
- # Version number string support
- Version.h
- Version.cpp
-
- # network stuffs
- net/NetAction.h
- net/MD5EtagDownload.h
- net/MD5EtagDownload.cpp
- net/ByteArrayDownload.h
- net/ByteArrayDownload.cpp
- net/CacheDownload.h
- net/CacheDownload.cpp
- net/NetJob.h
- net/NetJob.cpp
- net/HttpMetaCache.h
- net/HttpMetaCache.cpp
- net/PasteUpload.h
- net/PasteUpload.cpp
- net/URLConstants.h
- net/URLConstants.cpp
-
- # Yggdrasil login stuff
- minecraft/auth/AuthSession.h
- minecraft/auth/AuthSession.cpp
- minecraft/auth/MojangAccountList.h
- minecraft/auth/MojangAccountList.cpp
- minecraft/auth/MojangAccount.h
- minecraft/auth/MojangAccount.cpp
- minecraft/auth/YggdrasilTask.h
- minecraft/auth/YggdrasilTask.cpp
- minecraft/auth/flows/AuthenticateTask.h
- minecraft/auth/flows/AuthenticateTask.cpp
- minecraft/auth/flows/RefreshTask.cpp
- minecraft/auth/flows/RefreshTask.cpp
- minecraft/auth/flows/ValidateTask.h
- minecraft/auth/flows/ValidateTask.cpp
-
- # Game launch logic
- launch/steps/CheckJava.cpp
- launch/steps/CheckJava.h
- launch/steps/LaunchMinecraft.cpp
- launch/steps/LaunchMinecraft.h
- launch/steps/ModMinecraftJar.cpp
- launch/steps/ModMinecraftJar.h
- launch/steps/PostLaunchCommand.cpp
- launch/steps/PostLaunchCommand.h
- launch/steps/PreLaunchCommand.cpp
- launch/steps/PreLaunchCommand.h
- launch/steps/TextPrint.cpp
- launch/steps/TextPrint.h
- launch/steps/Update.cpp
- launch/steps/Update.h
- launch/LaunchStep.cpp
- launch/LaunchStep.h
- launch/LaunchTask.cpp
- launch/LaunchTask.h
- launch/LoggedProcess.cpp
- launch/LoggedProcess.h
- launch/MessageLevel.cpp
- launch/MessageLevel.h
-
- # Update system
- updater/GoUpdate.h
- updater/GoUpdate.cpp
- updater/UpdateChecker.h
- updater/UpdateChecker.cpp
- updater/DownloadTask.h
- updater/DownloadTask.cpp
-
- # Notifications - short warning messages
- notifications/NotificationChecker.h
- notifications/NotificationChecker.cpp
-
- # News System
- news/NewsChecker.h
- news/NewsChecker.cpp
- news/NewsEntry.h
- news/NewsEntry.cpp
-
- # Status system
- status/StatusChecker.h
- status/StatusChecker.cpp
-
- # Minecraft support
- minecraft/onesix/OneSixUpdate.h
- minecraft/onesix/OneSixUpdate.cpp
- minecraft/onesix/OneSixInstance.h
- minecraft/onesix/OneSixInstance.cpp
- minecraft/onesix/OneSixProfileStrategy.cpp
- minecraft/onesix/OneSixProfileStrategy.h
- minecraft/onesix/OneSixVersionFormat.cpp
- minecraft/onesix/OneSixVersionFormat.h
- minecraft/legacy/LegacyUpdate.h
- minecraft/legacy/LegacyUpdate.cpp
- minecraft/legacy/LegacyInstance.h
- minecraft/legacy/LegacyInstance.cpp
- minecraft/legacy/LwjglVersionList.h
- minecraft/legacy/LwjglVersionList.cpp
- minecraft/GradleSpecifier.h
- minecraft/MinecraftProfile.cpp
- minecraft/MinecraftProfile.h
- minecraft/MojangVersionFormat.cpp
- minecraft/MojangVersionFormat.h
- minecraft/JarMod.h
- minecraft/MinecraftInstance.cpp
- minecraft/MinecraftInstance.h
- minecraft/MinecraftVersion.cpp
- minecraft/MinecraftVersion.h
- minecraft/MinecraftVersionList.cpp
- minecraft/MinecraftVersionList.h
- minecraft/Rule.cpp
- minecraft/Rule.h
- minecraft/OpSys.cpp
- minecraft/OpSys.h
- minecraft/ParseUtils.cpp
- minecraft/ParseUtils.h
- minecraft/ProfileUtils.cpp
- minecraft/ProfileUtils.h
- minecraft/ProfileStrategy.h
- minecraft/Library.cpp
- minecraft/Library.h
- minecraft/MojangDownloadInfo.h
- minecraft/VersionBuildError.h
- minecraft/VersionFile.cpp
- minecraft/VersionFile.h
- minecraft/ProfilePatch.h
- minecraft/VersionFilterData.h
- minecraft/VersionFilterData.cpp
- minecraft/Mod.h
- minecraft/Mod.cpp
- minecraft/ModList.h
- minecraft/ModList.cpp
- minecraft/World.h
- minecraft/World.cpp
- minecraft/WorldList.h
- minecraft/WorldList.cpp
-
- # FTB
- minecraft/ftb/OneSixFTBInstance.h
- minecraft/ftb/OneSixFTBInstance.cpp
- minecraft/ftb/LegacyFTBInstance.h
- minecraft/ftb/LegacyFTBInstance.cpp
- minecraft/ftb/FTBProfileStrategy.h
- minecraft/ftb/FTBProfileStrategy.cpp
- minecraft/ftb/FTBPlugin.h
- minecraft/ftb/FTBPlugin.cpp
-
- # A Recursive file system watcher
- RecursiveFileSystemWatcher.h
- RecursiveFileSystemWatcher.cpp
-
- # the screenshots feature
- screenshots/Screenshot.h
- screenshots/ImgurUpload.h
- screenshots/ImgurUpload.cpp
- screenshots/ImgurAlbumCreation.h
- screenshots/ImgurAlbumCreation.cpp
-
- # Tasks
- tasks/Task.h
- tasks/Task.cpp
- tasks/ThreadTask.h
- tasks/ThreadTask.cpp
- tasks/SequentialTask.h
- tasks/SequentialTask.cpp
-
- # Settings
- settings/INIFile.cpp
- settings/INIFile.h
- settings/INISettingsObject.cpp
- settings/INISettingsObject.h
- settings/OverrideSetting.cpp
- settings/OverrideSetting.h
- settings/PassthroughSetting.cpp
- settings/PassthroughSetting.h
- settings/Setting.cpp
- settings/Setting.h
- settings/SettingsObject.cpp
- settings/SettingsObject.h
-
- # Java related code
- java/JavaChecker.h
- java/JavaChecker.cpp
- java/JavaCheckerJob.h
- java/JavaCheckerJob.cpp
- java/JavaInstall.h
- java/JavaInstall.cpp
- java/JavaInstallList.h
- java/JavaInstallList.cpp
- java/JavaUtils.h
- java/JavaUtils.cpp
- java/JavaVersion.h
- java/JavaVersion.cpp
-
- # Assets
- minecraft/AssetsUtils.h
- minecraft/AssetsUtils.cpp
-
- # Forge and all things forge related
- minecraft/forge/ForgeVersion.h
- minecraft/forge/ForgeVersion.cpp
- minecraft/forge/ForgeVersionList.h
- minecraft/forge/ForgeVersionList.cpp
- minecraft/forge/ForgeXzDownload.h
- minecraft/forge/ForgeXzDownload.cpp
- minecraft/forge/LegacyForge.h
- minecraft/forge/LegacyForge.cpp
- minecraft/forge/ForgeInstaller.h
- minecraft/forge/ForgeInstaller.cpp
-
- # Liteloader and related things
- minecraft/liteloader/LiteLoaderInstaller.h
- minecraft/liteloader/LiteLoaderInstaller.cpp
- minecraft/liteloader/LiteLoaderVersionList.h
- minecraft/liteloader/LiteLoaderVersionList.cpp
-
- # Translations
- trans/TranslationDownloader.h
- trans/TranslationDownloader.cpp
-
- # Tools
- tools/BaseExternalTool.cpp
- tools/BaseExternalTool.h
- tools/BaseProfiler.cpp
- tools/BaseProfiler.h
- tools/JProfiler.cpp
- tools/JProfiler.h
- tools/JVisualVM.cpp
- tools/JVisualVM.h
- tools/MCEditTool.cpp
- tools/MCEditTool.h
-
- # Wonko
- wonko/tasks/BaseWonkoEntityRemoteLoadTask.cpp
- wonko/tasks/BaseWonkoEntityRemoteLoadTask.h
- wonko/tasks/BaseWonkoEntityLocalLoadTask.cpp
- wonko/tasks/BaseWonkoEntityLocalLoadTask.h
- wonko/format/WonkoFormatV1.cpp
- wonko/format/WonkoFormatV1.h
- wonko/format/WonkoFormat.cpp
- wonko/format/WonkoFormat.h
- wonko/BaseWonkoEntity.cpp
- wonko/BaseWonkoEntity.h
- wonko/WonkoVersionList.cpp
- wonko/WonkoVersionList.h
- wonko/WonkoVersion.cpp
- wonko/WonkoVersion.h
- wonko/WonkoIndex.cpp
- wonko/WonkoIndex.h
- wonko/WonkoUtil.cpp
- wonko/WonkoUtil.h
- wonko/WonkoReference.cpp
- wonko/WonkoReference.h
-)
-################################ COMPILE ################################
-
-# we need zlib
-find_package(ZLIB REQUIRED)
-
-add_library(MultiMC_logic SHARED ${LOGIC_SOURCES})
-set_target_properties(MultiMC_logic PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1)
-
-generate_export_header(MultiMC_logic)
-
-# Link
-target_link_libraries(MultiMC_logic xz-embedded unpack200 ${QUAZIP_LIBRARIES} nbt++ ${ZLIB_LIBRARIES})
-qt5_use_modules(MultiMC_logic Core Xml Network Concurrent)
-add_dependencies(MultiMC_logic QuaZIP)
-
-# Mark and export headers
-target_include_directories(MultiMC_logic PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" PRIVATE "${ZLIB_INCLUDE_DIRS}")
diff --git a/libraries/logic/Commandline.cpp b/libraries/logic/Commandline.cpp
deleted file mode 100644
index 9a8ddbf1..00000000
--- a/libraries/logic/Commandline.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
- *
- * 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 "Commandline.h"
-
-/**
- * @file libutil/src/cmdutils.cpp
- */
-
-namespace Commandline
-{
-
-// commandline splitter
-QStringList splitArgs(QString args)
-{
- QStringList argv;
- QString current;
- bool escape = false;
- QChar inquotes;
- for (int i = 0; i < args.length(); i++)
- {
- QChar cchar = args.at(i);
-
- // \ escaped
- if (escape)
- {
- current += cchar;
- escape = false;
- // in "quotes"
- }
- else if (!inquotes.isNull())
- {
- if (cchar == 0x5C)
- escape = true;
- else if (cchar == inquotes)
- inquotes = 0;
- else
- current += cchar;
- // otherwise
- }
- else
- {
- if (cchar == 0x20)
- {
- if (!current.isEmpty())
- {
- argv << current;
- current.clear();
- }
- }
- else if (cchar == 0x22 || cchar == 0x27)
- inquotes = cchar;
- else
- current += cchar;
- }
- }
- if (!current.isEmpty())
- argv << current;
- return argv;
-}
-
-Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle)
-{
- m_flagStyle = flagStyle;
- m_argStyle = argStyle;
-}
-
-// styles setter/getter
-void Parser::setArgumentStyle(ArgumentStyle::Enum style)
-{
- m_argStyle = style;
-}
-ArgumentStyle::Enum Parser::argumentStyle()
-{
- return m_argStyle;
-}
-
-void Parser::setFlagStyle(FlagStyle::Enum style)
-{
- m_flagStyle = style;
-}
-FlagStyle::Enum Parser::flagStyle()
-{
- return m_flagStyle;
-}
-
-// setup methods
-void Parser::addSwitch(QString name, bool def)
-{
- if (m_params.contains(name))
- throw "Name not unique";
-
- OptionDef *param = new OptionDef;
- param->type = otSwitch;
- param->name = name;
- param->metavar = QString("<%1>").arg(name);
- param->def = def;
-
- m_options[name] = param;
- m_params[name] = (CommonDef *)param;
- m_optionList.append(param);
-}
-
-void Parser::addOption(QString name, QVariant def)
-{
- if (m_params.contains(name))
- throw "Name not unique";
-
- OptionDef *param = new OptionDef;
- param->type = otOption;
- param->name = name;
- param->metavar = QString("<%1>").arg(name);
- param->def = def;
-
- m_options[name] = param;
- m_params[name] = (CommonDef *)param;
- m_optionList.append(param);
-}
-
-void Parser::addArgument(QString name, bool required, QVariant def)
-{
- if (m_params.contains(name))
- throw "Name not unique";
-
- PositionalDef *param = new PositionalDef;
- param->name = name;
- param->def = def;
- param->required = required;
- param->metavar = name;
-
- m_positionals.append(param);
- m_params[name] = (CommonDef *)param;
-}
-
-void Parser::addDocumentation(QString name, QString doc, QString metavar)
-{
- if (!m_params.contains(name))
- throw "Name does not exist";
-
- CommonDef *param = m_params[name];
- param->doc = doc;
- if (!metavar.isNull())
- param->metavar = metavar;
-}
-
-void Parser::addShortOpt(QString name, QChar flag)
-{
- if (!m_params.contains(name))
- throw "Name does not exist";
- if (!m_options.contains(name))
- throw "Name is not an Option or Swtich";
-
- OptionDef *param = m_options[name];
- m_flags[flag] = param;
- param->flag = flag;
-}
-
-// help methods
-QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
-{
- QStringList help;
- help << compileUsage(progName, useFlags) << "\r\n";
-
- // positionals
- if (!m_positionals.isEmpty())
- {
- help << "\r\n";
- help << "Positional arguments:\r\n";
- QListIterator<PositionalDef *> it2(m_positionals);
- while (it2.hasNext())
- {
- PositionalDef *param = it2.next();
- help << " " << param->metavar;
- help << " " << QString(helpIndent - param->metavar.length() - 1, ' ');
- help << param->doc << "\r\n";
- }
- }
-
- // Options
- if (!m_optionList.isEmpty())
- {
- help << "\r\n";
- QString optPrefix, flagPrefix;
- getPrefix(optPrefix, flagPrefix);
-
- help << "Options & Switches:\r\n";
- QListIterator<OptionDef *> it(m_optionList);
- while (it.hasNext())
- {
- OptionDef *option = it.next();
- help << " ";
- int nameLength = optPrefix.length() + option->name.length();
- if (!option->flag.isNull())
- {
- nameLength += 3 + flagPrefix.length();
- help << flagPrefix << option->flag << ", ";
- }
- help << optPrefix << option->name;
- if (option->type == otOption)
- {
- QString arg = QString("%1%2").arg(
- ((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
- nameLength += arg.length();
- help << arg;
- }
- help << " " << QString(helpIndent - nameLength - 1, ' ');
- help << option->doc << "\r\n";
- }
- }
-
- return help.join("");
-}
-
-QString Parser::compileUsage(QString progName, bool useFlags)
-{
- QStringList usage;
- usage << "Usage: " << progName;
-
- QString optPrefix, flagPrefix;
- getPrefix(optPrefix, flagPrefix);
-
- // options
- QListIterator<OptionDef *> it(m_optionList);
- while (it.hasNext())
- {
- OptionDef *option = it.next();
- usage << " [";
- if (!option->flag.isNull() && useFlags)
- usage << flagPrefix << option->flag;
- else
- usage << optPrefix << option->name;
- if (option->type == otOption)
- usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
- usage << "]";
- }
-
- // arguments
- QListIterator<PositionalDef *> it2(m_positionals);
- while (it2.hasNext())
- {
- PositionalDef *param = it2.next();
- usage << " " << (param->required ? "<" : "[");
- usage << param->metavar;
- usage << (param->required ? ">" : "]");
- }
-
- return usage.join("");
-}
-
-// parsing
-QHash<QString, QVariant> Parser::parse(QStringList argv)
-{
- QHash<QString, QVariant> map;
-
- QStringListIterator it(argv);
- QString programName = it.next();
-
- QString optionPrefix;
- QString flagPrefix;
- QListIterator<PositionalDef *> positionals(m_positionals);
- QStringList expecting;
-
- getPrefix(optionPrefix, flagPrefix);
-
- while (it.hasNext())
- {
- QString arg = it.next();
-
- if (!expecting.isEmpty())
- // we were expecting an argument
- {
- QString name = expecting.first();
-/*
- if (map.contains(name))
- throw ParsingError(
- QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
-*/
- map[name] = QVariant(arg);
-
- expecting.removeFirst();
- continue;
- }
-
- if (arg.startsWith(optionPrefix))
- // we have an option
- {
- // qDebug("Found option %s", qPrintable(arg));
-
- QString name = arg.mid(optionPrefix.length());
- QString equals;
-
- if ((m_argStyle == ArgumentStyle::Equals ||
- m_argStyle == ArgumentStyle::SpaceAndEquals) &&
- name.contains("="))
- {
- int i = name.indexOf("=");
- equals = name.mid(i + 1);
- name = name.left(i);
- }
-
- if (m_options.contains(name))
- {
- /*
- if (map.contains(name))
- throw ParsingError(QString("Option %2%1 was given multiple times")
- .arg(name, optionPrefix));
-*/
- OptionDef *option = m_options[name];
- if (option->type == otSwitch)
- map[name] = true;
- else // if (option->type == otOption)
- {
- if (m_argStyle == ArgumentStyle::Space)
- expecting.append(name);
- else if (!equals.isNull())
- map[name] = equals;
- else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
- expecting.append(name);
- else
- throw ParsingError(QString("Option %2%1 reqires an argument.")
- .arg(name, optionPrefix));
- }
-
- continue;
- }
-
- throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
- }
-
- if (arg.startsWith(flagPrefix))
- // we have (a) flag(s)
- {
- // qDebug("Found flags %s", qPrintable(arg));
-
- QString flags = arg.mid(flagPrefix.length());
- QString equals;
-
- if ((m_argStyle == ArgumentStyle::Equals ||
- m_argStyle == ArgumentStyle::SpaceAndEquals) &&
- flags.contains("="))
- {
- int i = flags.indexOf("=");
- equals = flags.mid(i + 1);
- flags = flags.left(i);
- }
-
- for (int i = 0; i < flags.length(); i++)
- {
- QChar flag = flags.at(i);
-
- if (!m_flags.contains(flag))
- throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
-
- OptionDef *option = m_flags[flag];
-/*
- if (map.contains(option->name))
- throw ParsingError(QString("Option %2%1 was given multiple times")
- .arg(option->name, optionPrefix));
-*/
- if (option->type == otSwitch)
- map[option->name] = true;
- else // if (option->type == otOption)
- {
- if (m_argStyle == ArgumentStyle::Space)
- expecting.append(option->name);
- else if (!equals.isNull())
- if (i == flags.length() - 1)
- map[option->name] = equals;
- else
- throw ParsingError(QString("Flag %4%2 of Argument-requiring Option "
- "%1 not last flag in %4%3")
- .arg(option->name, flag, flags, flagPrefix));
- else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
- expecting.append(option->name);
- else
- throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)")
- .arg(option->name, flag, flagPrefix));
- }
- }
-
- continue;
- }
-
- // must be a positional argument
- if (!positionals.hasNext())
- throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
-
- PositionalDef *param = positionals.next();
-
- map[param->name] = arg;
- }
-
- // check if we're missing something
- if (!expecting.isEmpty())
- throw ParsingError(QString("Was still expecting arguments for %2%1").arg(
- expecting.join(QString(", ") + optionPrefix), optionPrefix));
-
- while (positionals.hasNext())
- {
- PositionalDef *param = positionals.next();
- if (param->required)
- throw ParsingError(
- QString("Missing required positional argument '%1'").arg(param->name));
- else
- map[param->name] = param->def;
- }
-
- // fill out gaps
- QListIterator<OptionDef *> iter(m_optionList);
- while (iter.hasNext())
- {
- OptionDef *option = iter.next();
- if (!map.contains(option->name))
- map[option->name] = option->def;
- }
-
- return map;
-}
-
-// clear defs
-void Parser::clear()
-{
- m_flags.clear();
- m_params.clear();
- m_options.clear();
-
- QMutableListIterator<OptionDef *> it(m_optionList);
- while (it.hasNext())
- {
- OptionDef *option = it.next();
- it.remove();
- delete option;
- }
-
- QMutableListIterator<PositionalDef *> it2(m_positionals);
- while (it2.hasNext())
- {
- PositionalDef *arg = it2.next();
- it2.remove();
- delete arg;
- }
-}
-
-// Destructor
-Parser::~Parser()
-{
- clear();
-}
-
-// getPrefix
-void Parser::getPrefix(QString &opt, QString &flag)
-{
- if (m_flagStyle == FlagStyle::Windows)
- opt = flag = "/";
- else if (m_flagStyle == FlagStyle::Unix)
- opt = flag = "-";
- // else if (m_flagStyle == FlagStyle::GNU)
- else
- {
- opt = "--";
- flag = "-";
- }
-}
-
-// ParsingError
-ParsingError::ParsingError(const QString &what) : std::runtime_error(what.toStdString())
-{
-}
-} \ No newline at end of file
diff --git a/libraries/logic/Commandline.h b/libraries/logic/Commandline.h
deleted file mode 100644
index bee02bad..00000000
--- a/libraries/logic/Commandline.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <exception>
-#include <stdexcept>
-
-#include <QString>
-#include <QVariant>
-#include <QHash>
-#include <QStringList>
-
-#include "multimc_logic_export.h"
-
-/**
- * @file libutil/include/cmdutils.h
- * @brief commandline parsing and processing utilities
- */
-
-namespace Commandline
-{
-
-/**
- * @brief split a string into argv items like a shell would do
- * @param args the argument string
- * @return a QStringList containing all arguments
- */
-MULTIMC_LOGIC_EXPORT QStringList splitArgs(QString args);
-
-/**
- * @brief The FlagStyle enum
- * Specifies how flags are decorated
- */
-
-namespace FlagStyle
-{
-enum Enum
-{
- GNU, /**< --option and -o (GNU Style) */
- Unix, /**< -option and -o (Unix Style) */
- Windows, /**< /option and /o (Windows Style) */
-#ifdef Q_OS_WIN32
- Default = Windows
-#else
- Default = GNU
-#endif
-};
-}
-
-/**
- * @brief The ArgumentStyle enum
- */
-namespace ArgumentStyle
-{
-enum Enum
-{
- Space, /**< --option=value */
- Equals, /**< --option value */
- SpaceAndEquals, /**< --option[= ]value */
-#ifdef Q_OS_WIN32
- Default = Equals
-#else
- Default = SpaceAndEquals
-#endif
-};
-}
-
-/**
- * @brief The ParsingError class
- */
-class MULTIMC_LOGIC_EXPORT ParsingError : public std::runtime_error
-{
-public:
- ParsingError(const QString &what);
-};
-
-/**
- * @brief The Parser class
- */
-class MULTIMC_LOGIC_EXPORT Parser
-{
-public:
- /**
- * @brief Parser constructor
- * @param flagStyle the FlagStyle to use in this Parser
- * @param argStyle the ArgumentStyle to use in this Parser
- */
- Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
- ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
-
- /**
- * @brief set the flag style
- * @param style
- */
- void setFlagStyle(FlagStyle::Enum style);
-
- /**
- * @brief get the flag style
- * @return
- */
- FlagStyle::Enum flagStyle();
-
- /**
- * @brief set the argument style
- * @param style
- */
- void setArgumentStyle(ArgumentStyle::Enum style);
-
- /**
- * @brief get the argument style
- * @return
- */
- ArgumentStyle::Enum argumentStyle();
-
- /**
- * @brief define a boolean switch
- * @param name the parameter name
- * @param def the default value
- */
- void addSwitch(QString name, bool def = false);
-
- /**
- * @brief define an option that takes an additional argument
- * @param name the parameter name
- * @param def the default value
- */
- void addOption(QString name, QVariant def = QVariant());
-
- /**
- * @brief define a positional argument
- * @param name the parameter name
- * @param required wether this argument is required
- * @param def the default value
- */
- void addArgument(QString name, bool required = true, QVariant def = QVariant());
-
- /**
- * @brief adds a flag to an existing parameter
- * @param name the (existing) parameter name
- * @param flag the flag character
- * @see addSwitch addArgument addOption
- * Note: any one parameter can only have one flag
- */
- void addShortOpt(QString name, QChar flag);
-
- /**
- * @brief adds documentation to a Parameter
- * @param name the parameter name
- * @param metavar a string to be displayed as placeholder for the value
- * @param doc a QString containing the documentation
- * Note: on positional arguments, metavar replaces the name as displayed.
- * on options , metavar replaces the value placeholder
- */
- void addDocumentation(QString name, QString doc, QString metavar = QString());
-
- /**
- * @brief generate a help message
- * @param progName the program name to use in the help message
- * @param helpIndent how much the parameter documentation should be indented
- * @param flagsInUsage whether we should use flags instead of options in the usage
- * @return a help message
- */
- QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
-
- /**
- * @brief generate a short usage message
- * @param progName the program name to use in the usage message
- * @param useFlags whether we should use flags instead of options
- * @return a usage message
- */
- QString compileUsage(QString progName, bool useFlags = true);
-
- /**
- * @brief parse
- * @param argv a QStringList containing the program ARGV
- * @return a QHash mapping argument names to their values
- */
- QHash<QString, QVariant> parse(QStringList argv);
-
- /**
- * @brief clear all definitions
- */
- void clear();
-
- ~Parser();
-
-private:
- FlagStyle::Enum m_flagStyle;
- ArgumentStyle::Enum m_argStyle;
-
- enum OptionType
- {
- otSwitch,
- otOption
- };
-
- // Important: the common part MUST BE COMMON ON ALL THREE structs
- struct CommonDef
- {
- QString name;
- QString doc;
- QString metavar;
- QVariant def;
- };
-
- struct OptionDef
- {
- // common
- QString name;
- QString doc;
- QString metavar;
- QVariant def;
- // option
- OptionType type;
- QChar flag;
- };
-
- struct PositionalDef
- {
- // common
- QString name;
- QString doc;
- QString metavar;
- QVariant def;
- // positional
- bool required;
- };
-
- QHash<QString, OptionDef *> m_options;
- QHash<QChar, OptionDef *> m_flags;
- QHash<QString, CommonDef *> m_params;
- QList<PositionalDef *> m_positionals;
- QList<OptionDef *> m_optionList;
-
- void getPrefix(QString &opt, QString &flag);
-};
-}
diff --git a/libraries/logic/DefaultVariable.h b/libraries/logic/DefaultVariable.h
deleted file mode 100644
index 38d7ecc2..00000000
--- a/libraries/logic/DefaultVariable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-template <typename T>
-class DefaultVariable
-{
-public:
- DefaultVariable(const T & value)
- {
- defaultValue = value;
- }
- DefaultVariable<T> & operator =(const T & value)
- {
- currentValue = value;
- is_default = currentValue == defaultValue;
- is_explicit = true;
- return *this;
- }
- operator const T &() const
- {
- return is_default ? defaultValue : currentValue;
- }
- bool isDefault() const
- {
- return is_default;
- }
- bool isExplicit() const
- {
- return is_explicit;
- }
-private:
- T currentValue;
- T defaultValue;
- bool is_default = true;
- bool is_explicit = false;
-};
diff --git a/libraries/logic/Env.cpp b/libraries/logic/Env.cpp
deleted file mode 100644
index cc0c5981..00000000
--- a/libraries/logic/Env.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-#include "Env.h"
-#include "net/HttpMetaCache.h"
-#include "BaseVersion.h"
-#include "BaseVersionList.h"
-#include <QDir>
-#include <QNetworkProxy>
-#include <QNetworkAccessManager>
-#include <QDebug>
-#include "tasks/Task.h"
-#include "wonko/WonkoIndex.h"
-#include <QDebug>
-
-/*
- * The *NEW* global rat nest of an object. Handle with care.
- */
-
-Env::Env()
-{
- m_qnam = std::make_shared<QNetworkAccessManager>();
-}
-
-void Env::destroy()
-{
- m_metacache.reset();
- m_qnam.reset();
- m_versionLists.clear();
-}
-
-Env& Env::Env::getInstance()
-{
- static Env instance;
- return instance;
-}
-
-std::shared_ptr< HttpMetaCache > Env::metacache()
-{
- Q_ASSERT(m_metacache != nullptr);
- return m_metacache;
-}
-
-std::shared_ptr< QNetworkAccessManager > Env::qnam()
-{
- return m_qnam;
-}
-
-/*
-class NullVersion : public BaseVersion
-{
- Q_OBJECT
-public:
- virtual QString name()
- {
- return "null";
- }
- virtual QString descriptor()
- {
- return "null";
- }
- virtual QString typeString() const
- {
- return "Null";
- }
-};
-
-class NullTask: public Task
-{
- Q_OBJECT
-public:
- virtual void executeTask()
- {
- emitFailed(tr("Nothing to do."));
- }
-};
-
-class NullVersionList: public BaseVersionList
-{
- Q_OBJECT
-public:
- virtual const BaseVersionPtr at(int i) const
- {
- return std::make_shared<NullVersion>();
- }
- virtual int count() const
- {
- return 0;
- };
- virtual Task* getLoadTask()
- {
- return new NullTask;
- }
- virtual bool isLoaded()
- {
- return false;
- }
- virtual void sort()
- {
- }
- virtual void updateListData(QList< BaseVersionPtr >)
- {
- }
-};
-*/
-
-BaseVersionPtr Env::getVersion(QString component, QString version)
-{
- auto list = getVersionList(component);
- if(!list)
- {
- return nullptr;
- }
- return list->findVersion(version);
-}
-
-std::shared_ptr< BaseVersionList > Env::getVersionList(QString component)
-{
- auto iter = m_versionLists.find(component);
- if(iter != m_versionLists.end())
- {
- return *iter;
- }
- //return std::make_shared<NullVersionList>();
- return nullptr;
-}
-
-void Env::registerVersionList(QString name, std::shared_ptr< BaseVersionList > vlist)
-{
- m_versionLists[name] = vlist;
-}
-
-std::shared_ptr<WonkoIndex> Env::wonkoIndex()
-{
- if (!m_wonkoIndex)
- {
- m_wonkoIndex = std::make_shared<WonkoIndex>();
- }
- return m_wonkoIndex;
-}
-
-
-void Env::initHttpMetaCache()
-{
- m_metacache.reset(new HttpMetaCache("metacache"));
- m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath());
- m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath());
- m_metacache->addBase("versions", QDir("versions").absolutePath());
- m_metacache->addBase("libraries", QDir("libraries").absolutePath());
- m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
- m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath());
- m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath());
- m_metacache->addBase("general", QDir("cache").absolutePath());
- m_metacache->addBase("skins", QDir("accounts/skins").absolutePath());
- m_metacache->addBase("root", QDir::currentPath());
- m_metacache->addBase("translations", QDir("translations").absolutePath());
- m_metacache->addBase("icons", QDir("cache/icons").absolutePath());
- m_metacache->addBase("wonko", QDir("cache/wonko").absolutePath());
- m_metacache->Load();
-}
-
-void Env::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password)
-{
- // Set the application proxy settings.
- if (proxyTypeStr == "SOCKS5")
- {
- QNetworkProxy::setApplicationProxy(
- QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password));
- }
- else if (proxyTypeStr == "HTTP")
- {
- QNetworkProxy::setApplicationProxy(
- QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password));
- }
- else if (proxyTypeStr == "None")
- {
- // If we have no proxy set, set no proxy and return.
- QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
- }
- else
- {
- // If we have "Default" selected, set Qt to use the system proxy settings.
- QNetworkProxyFactory::setUseSystemConfiguration(true);
- }
-
- qDebug() << "Detecting proxy settings...";
- QNetworkProxy proxy = QNetworkProxy::applicationProxy();
- if (m_qnam.get())
- m_qnam->setProxy(proxy);
- QString proxyDesc;
- if (proxy.type() == QNetworkProxy::NoProxy)
- {
- qDebug() << "Using no proxy is an option!";
- return;
- }
- switch (proxy.type())
- {
- case QNetworkProxy::DefaultProxy:
- proxyDesc = "Default proxy: ";
- break;
- case QNetworkProxy::Socks5Proxy:
- proxyDesc = "Socks5 proxy: ";
- break;
- case QNetworkProxy::HttpProxy:
- proxyDesc = "HTTP proxy: ";
- break;
- case QNetworkProxy::HttpCachingProxy:
- proxyDesc = "HTTP caching: ";
- break;
- case QNetworkProxy::FtpCachingProxy:
- proxyDesc = "FTP caching: ";
- break;
- default:
- proxyDesc = "DERP proxy: ";
- break;
- }
- proxyDesc += QString("%3@%1:%2 pass %4")
- .arg(proxy.hostName())
- .arg(proxy.port())
- .arg(proxy.user())
- .arg(proxy.password());
- qDebug() << proxyDesc;
-}
-
-#include "Env.moc"
diff --git a/libraries/logic/Env.h b/libraries/logic/Env.h
deleted file mode 100644
index 4d8945d7..00000000
--- a/libraries/logic/Env.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <memory>
-#include <QString>
-#include <QMap>
-
-#include "multimc_logic_export.h"
-
-class QNetworkAccessManager;
-class HttpMetaCache;
-class BaseVersionList;
-class BaseVersion;
-class WonkoIndex;
-
-#if defined(ENV)
- #undef ENV
-#endif
-#define ENV (Env::getInstance())
-
-class MULTIMC_LOGIC_EXPORT Env
-{
- friend class MultiMC;
-private:
- Env();
-public:
- static Env& getInstance();
-
- // call when Qt stuff is being torn down
- void destroy();
-
- std::shared_ptr<QNetworkAccessManager> qnam();
-
- std::shared_ptr<HttpMetaCache> metacache();
-
- /// init the cache. FIXME: possible future hook point
- void initHttpMetaCache();
-
- /// Updates the application proxy settings from the settings object.
- void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password);
-
- /// get a version list by name
- std::shared_ptr<BaseVersionList> getVersionList(QString component);
-
- /// get a version by list name and version name
- std::shared_ptr<BaseVersion> getVersion(QString component, QString version);
-
- void registerVersionList(QString name, std::shared_ptr<BaseVersionList> vlist);
-
- std::shared_ptr<WonkoIndex> wonkoIndex();
-
- QString wonkoRootUrl() const { return m_wonkoRootUrl; }
- void setWonkoRootUrl(const QString &url) { m_wonkoRootUrl = url; }
-
-protected:
- std::shared_ptr<QNetworkAccessManager> m_qnam;
- std::shared_ptr<HttpMetaCache> m_metacache;
- QMap<QString, std::shared_ptr<BaseVersionList>> m_versionLists;
- std::shared_ptr<WonkoIndex> m_wonkoIndex;
- QString m_wonkoRootUrl;
-};
diff --git a/libraries/logic/Exception.h b/libraries/logic/Exception.h
deleted file mode 100644
index 30c7aa45..00000000
--- a/libraries/logic/Exception.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed under the Apache-2.0 license. See README.md for details.
-
-#pragma once
-
-#include <QString>
-#include <QDebug>
-#include <exception>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT Exception : public std::exception
-{
-public:
- Exception(const QString &message) : std::exception(), m_message(message)
- {
- qCritical() << "Exception:" << message;
- }
- Exception(const Exception &other)
- : std::exception(), m_message(other.cause())
- {
- }
- virtual ~Exception() noexcept {}
- const char *what() const noexcept
- {
- return m_message.toLatin1().constData();
- }
- QString cause() const
- {
- return m_message;
- }
-
-private:
- QString m_message;
-};
diff --git a/libraries/logic/FileSystem.cpp b/libraries/logic/FileSystem.cpp
deleted file mode 100644
index 049f1e38..00000000
--- a/libraries/logic/FileSystem.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-// Licensed under the Apache-2.0 license. See README.md for details.
-
-#include "FileSystem.h"
-
-#include <QDir>
-#include <QSaveFile>
-#include <QFileInfo>
-#include <QDebug>
-#include <QUrl>
-#include <QStandardPaths>
-
-namespace FS {
-
-void ensureExists(const QDir &dir)
-{
- if (!QDir().mkpath(dir.absolutePath()))
- {
- throw FileSystemException("Unable to create directory " + dir.dirName() + " (" +
- dir.absolutePath() + ")");
- }
-}
-
-void write(const QString &filename, const QByteArray &data)
-{
- ensureExists(QFileInfo(filename).dir());
- QSaveFile file(filename);
- if (!file.open(QSaveFile::WriteOnly))
- {
- throw FileSystemException("Couldn't open " + filename + " for writing: " +
- file.errorString());
- }
- if (data.size() != file.write(data))
- {
- throw FileSystemException("Error writing data to " + filename + ": " +
- file.errorString());
- }
- if (!file.commit())
- {
- throw FileSystemException("Error while committing data to " + filename + ": " +
- file.errorString());
- }
-}
-
-QByteArray read(const QString &filename)
-{
- QFile file(filename);
- if (!file.open(QFile::ReadOnly))
- {
- throw FileSystemException("Unable to open " + filename + " for reading: " +
- file.errorString());
- }
- const qint64 size = file.size();
- QByteArray data(int(size), 0);
- const qint64 ret = file.read(data.data(), size);
- if (ret == -1 || ret != size)
- {
- throw FileSystemException("Error reading data from " + filename + ": " +
- file.errorString());
- }
- return data;
-}
-
-bool ensureFilePathExists(QString filenamepath)
-{
- QFileInfo a(filenamepath);
- QDir dir;
- QString ensuredPath = a.path();
- bool success = dir.mkpath(ensuredPath);
- return success;
-}
-
-bool ensureFolderPathExists(QString foldernamepath)
-{
- QFileInfo a(foldernamepath);
- QDir dir;
- QString ensuredPath = a.filePath();
- bool success = dir.mkpath(ensuredPath);
- return success;
-}
-
-bool copy::operator()(const QString &offset)
-{
- //NOTE always deep copy on windows. the alternatives are too messy.
- #if defined Q_OS_WIN32
- m_followSymlinks = true;
- #endif
-
- auto src = PathCombine(m_src.absolutePath(), offset);
- auto dst = PathCombine(m_dst.absolutePath(), offset);
-
- QFileInfo currentSrc(src);
- if (!currentSrc.exists())
- return false;
-
- if(!m_followSymlinks && currentSrc.isSymLink())
- {
- qDebug() << "creating symlink" << src << " - " << dst;
- if (!ensureFilePathExists(dst))
- {
- qWarning() << "Cannot create path!";
- return false;
- }
- return QFile::link(currentSrc.symLinkTarget(), dst);
- }
- else if(currentSrc.isFile())
- {
- qDebug() << "copying file" << src << " - " << dst;
- if (!ensureFilePathExists(dst))
- {
- qWarning() << "Cannot create path!";
- return false;
- }
- return QFile::copy(src, dst);
- }
- else if(currentSrc.isDir())
- {
- qDebug() << "recursing" << offset;
- if (!ensureFolderPathExists(dst))
- {
- qWarning() << "Cannot create path!";
- return false;
- }
- QDir currentDir(src);
- for(auto & f : currentDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System))
- {
- auto inner_offset = PathCombine(offset, f);
- // ignore and skip stuff that matches the blacklist.
- if(m_blacklist && m_blacklist->matches(inner_offset))
- {
- continue;
- }
- if(!operator()(inner_offset))
- {
- return false;
- }
- }
- }
- else
- {
- qCritical() << "Copy ERROR: Unknown filesystem object:" << src;
- return false;
- }
- return true;
-}
-
-
-#if defined Q_OS_WIN32
-#include <windows.h>
-#include <string>
-#endif
-bool deletePath(QString path)
-{
- bool OK = true;
- QDir dir(path);
-
- if (!dir.exists())
- {
- return OK;
- }
- auto allEntries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
- QDir::AllDirs | QDir::Files,
- QDir::DirsFirst);
-
- for(auto & info: allEntries)
- {
-#if defined Q_OS_WIN32
- QString nativePath = QDir::toNativeSeparators(info.absoluteFilePath());
- auto wString = nativePath.toStdWString();
- DWORD dwAttrs = GetFileAttributesW(wString.c_str());
- // Windows: check for junctions, reparse points and other nasty things of that sort
- if(dwAttrs & FILE_ATTRIBUTE_REPARSE_POINT)
- {
- if (info.isFile())
- {
- OK &= QFile::remove(info.absoluteFilePath());
- }
- else if (info.isDir())
- {
- OK &= dir.rmdir(info.absoluteFilePath());
- }
- }
-#else
- // We do not trust Qt with reparse points, but do trust it with unix symlinks.
- if(info.isSymLink())
- {
- OK &= QFile::remove(info.absoluteFilePath());
- }
-#endif
- else if (info.isDir())
- {
- OK &= deletePath(info.absoluteFilePath());
- }
- else if (info.isFile())
- {
- OK &= QFile::remove(info.absoluteFilePath());
- }
- else
- {
- OK = false;
- qCritical() << "Delete ERROR: Unknown filesystem object:" << info.absoluteFilePath();
- }
- }
- OK &= dir.rmdir(dir.absolutePath());
- return OK;
-}
-
-
-QString PathCombine(QString path1, QString path2)
-{
- if(!path1.size())
- return path2;
- if(!path2.size())
- return path1;
- return QDir::cleanPath(path1 + QDir::separator() + path2);
-}
-
-QString PathCombine(QString path1, QString path2, QString path3)
-{
- return PathCombine(PathCombine(path1, path2), path3);
-}
-
-QString AbsolutePath(QString path)
-{
- return QFileInfo(path).absolutePath();
-}
-
-QString ResolveExecutable(QString path)
-{
- if (path.isEmpty())
- {
- return QString();
- }
- if(!path.contains('/'))
- {
- path = QStandardPaths::findExecutable(path);
- }
- QFileInfo pathInfo(path);
- if(!pathInfo.exists() || !pathInfo.isExecutable())
- {
- return QString();
- }
- return pathInfo.absoluteFilePath();
-}
-
-/**
- * Normalize path
- *
- * Any paths inside the current directory will be normalized to relative paths (to current)
- * Other paths will be made absolute
- */
-QString NormalizePath(QString path)
-{
- QDir a = QDir::currentPath();
- QString currentAbsolute = a.absolutePath();
-
- QDir b(path);
- QString newAbsolute = b.absolutePath();
-
- if (newAbsolute.startsWith(currentAbsolute))
- {
- return a.relativeFilePath(newAbsolute);
- }
- else
- {
- return newAbsolute;
- }
-}
-
-QString badFilenameChars = "\"\\/?<>:*|!";
-
-QString RemoveInvalidFilenameChars(QString string, QChar replaceWith)
-{
- for (int i = 0; i < string.length(); i++)
- {
- if (badFilenameChars.contains(string[i]))
- {
- string[i] = replaceWith;
- }
- }
- return string;
-}
-
-QString DirNameFromString(QString string, QString inDir)
-{
- int num = 0;
- QString baseName = RemoveInvalidFilenameChars(string, '-');
- QString dirName;
- do
- {
- if(num == 0)
- {
- dirName = baseName;
- }
- else
- {
- dirName = baseName + QString::number(num);;
- }
-
- // If it's over 9000
- if (num > 9000)
- return "";
- num++;
- } while (QFileInfo(PathCombine(inDir, dirName)).exists());
- return dirName;
-}
-
-// Does the directory path contain any '!'? If yes, return true, otherwise false.
-// (This is a problem for Java)
-bool checkProblemticPathJava(QDir folder)
-{
- QString pathfoldername = folder.absolutePath();
- return pathfoldername.contains("!", Qt::CaseInsensitive);
-}
-
-#include <QStandardPaths>
-#include <QFile>
-#include <QTextStream>
-
-// Win32 crap
-#if defined Q_OS_WIN
-
-#include <windows.h>
-#include <winnls.h>
-#include <shobjidl.h>
-#include <objbase.h>
-#include <objidl.h>
-#include <shlguid.h>
-#include <shlobj.h>
-
-bool called_coinit = false;
-
-HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args)
-{
- HRESULT hres;
-
- if (!called_coinit)
- {
- hres = CoInitialize(NULL);
- called_coinit = true;
-
- if (!SUCCEEDED(hres))
- {
- qWarning("Failed to initialize COM. Error 0x%08X", hres);
- return hres;
- }
- }
-
- IShellLink *link;
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
- (LPVOID *)&link);
-
- if (SUCCEEDED(hres))
- {
- IPersistFile *persistFile;
-
- link->SetPath(targetPath);
- link->SetArguments(args);
-
- hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
- if (SUCCEEDED(hres))
- {
- WCHAR wstr[MAX_PATH];
-
- MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
-
- hres = persistFile->Save(wstr, TRUE);
- persistFile->Release();
- }
- link->Release();
- }
- return hres;
-}
-
-#endif
-
-QString getDesktopDir()
-{
- return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
-}
-
-// Cross-platform Shortcut creation
-bool createShortCut(QString location, QString dest, QStringList args, QString name,
- QString icon)
-{
-#if defined Q_OS_LINUX
- location = PathCombine(location, name + ".desktop");
-
- QFile f(location);
- f.open(QIODevice::WriteOnly | QIODevice::Text);
- QTextStream stream(&f);
-
- QString argstring;
- if (!args.empty())
- argstring = " '" + args.join("' '") + "'";
-
- stream << "[Desktop Entry]"
- << "\n";
- stream << "Type=Application"
- << "\n";
- stream << "TryExec=" << dest.toLocal8Bit() << "\n";
- stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
- stream << "Name=" << name.toLocal8Bit() << "\n";
- stream << "Icon=" << icon.toLocal8Bit() << "\n";
-
- stream.flush();
- f.close();
-
- f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup |
- QFileDevice::ExeOther);
-
- return true;
-#elif defined Q_OS_WIN
- // TODO: Fix
- // QFile file(PathCombine(location, name + ".lnk"));
- // WCHAR *file_w;
- // WCHAR *dest_w;
- // WCHAR *args_w;
- // file.fileName().toWCharArray(file_w);
- // dest.toWCharArray(dest_w);
-
- // QString argStr;
- // for (int i = 0; i < args.count(); i++)
- // {
- // argStr.append(args[i]);
- // argStr.append(" ");
- // }
- // argStr.toWCharArray(args_w);
-
- // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
- return false;
-#else
- qWarning("Desktop Shortcuts not supported on your platform!");
- return false;
-#endif
-}
-}
diff --git a/libraries/logic/FileSystem.h b/libraries/logic/FileSystem.h
deleted file mode 100644
index 80637f90..00000000
--- a/libraries/logic/FileSystem.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed under the Apache-2.0 license. See README.md for details.
-
-#pragma once
-
-#include "Exception.h"
-#include "pathmatcher/IPathMatcher.h"
-
-#include "multimc_logic_export.h"
-#include <QDir>
-#include <QFlags>
-
-namespace FS
-{
-
-class MULTIMC_LOGIC_EXPORT FileSystemException : public ::Exception
-{
-public:
- FileSystemException(const QString &message) : Exception(message) {}
-};
-
-/**
- * write data to a file safely
- */
-MULTIMC_LOGIC_EXPORT void write(const QString &filename, const QByteArray &data);
-
-/**
- * read data from a file safely\
- */
-MULTIMC_LOGIC_EXPORT QByteArray read(const QString &filename);
-
-/**
- * Creates all the folders in a path for the specified path
- * last segment of the path is treated as a file name and is ignored!
- */
-MULTIMC_LOGIC_EXPORT bool ensureFilePathExists(QString filenamepath);
-
-/**
- * Creates all the folders in a path for the specified path
- * last segment of the path is treated as a folder name and is created!
- */
-MULTIMC_LOGIC_EXPORT bool ensureFolderPathExists(QString filenamepath);
-
-class MULTIMC_LOGIC_EXPORT copy
-{
-public:
- copy(const copy&) = delete;
- copy(const QString & src, const QString & dst)
- {
- m_src = src;
- m_dst = dst;
- }
- copy & followSymlinks(const bool follow)
- {
- m_followSymlinks = follow;
- return *this;
- }
- copy & blacklist(const IPathMatcher * filter)
- {
- m_blacklist = filter;
- return *this;
- }
- bool operator()()
- {
- return operator()(QString());
- }
-
-private:
- bool operator()(const QString &offset);
-
-private:
- bool m_followSymlinks = true;
- const IPathMatcher * m_blacklist = nullptr;
- QDir m_src;
- QDir m_dst;
-};
-
-/**
- * Delete a folder recursively
- */
-MULTIMC_LOGIC_EXPORT bool deletePath(QString path);
-
-MULTIMC_LOGIC_EXPORT QString PathCombine(QString path1, QString path2);
-MULTIMC_LOGIC_EXPORT QString PathCombine(QString path1, QString path2, QString path3);
-
-MULTIMC_LOGIC_EXPORT QString AbsolutePath(QString path);
-
-/**
- * Resolve an executable
- *
- * Will resolve:
- * single executable (by name)
- * relative path
- * absolute path
- *
- * @return absolute path to executable or null string
- */
-MULTIMC_LOGIC_EXPORT QString ResolveExecutable(QString path);
-
-/**
- * Normalize path
- *
- * Any paths inside the current directory will be normalized to relative paths (to current)
- * Other paths will be made absolute
- *
- * Returns false if the path logic somehow filed (and normalizedPath in invalid)
- */
-MULTIMC_LOGIC_EXPORT QString NormalizePath(QString path);
-
-MULTIMC_LOGIC_EXPORT QString RemoveInvalidFilenameChars(QString string, QChar replaceWith = '-');
-
-MULTIMC_LOGIC_EXPORT QString DirNameFromString(QString string, QString inDir = ".");
-
-/// Checks if the a given Path contains "!"
-MULTIMC_LOGIC_EXPORT bool checkProblemticPathJava(QDir folder);
-
-// Get the Directory representing the User's Desktop
-MULTIMC_LOGIC_EXPORT QString getDesktopDir();
-
-// Create a shortcut at *location*, pointing to *dest* called with the arguments *args*
-// call it *name* and assign it the icon *icon*
-// return true if operation succeeded
-MULTIMC_LOGIC_EXPORT bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation);
-}
diff --git a/libraries/logic/GZip.cpp b/libraries/logic/GZip.cpp
deleted file mode 100644
index 38605df6..00000000
--- a/libraries/logic/GZip.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "GZip.h"
-#include <zlib.h>
-#include <QByteArray>
-
-bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes)
-{
- if (compressedBytes.size() == 0)
- {
- uncompressedBytes = compressedBytes;
- return true;
- }
-
- unsigned uncompLength = compressedBytes.size();
- uncompressedBytes.clear();
- uncompressedBytes.resize(uncompLength);
-
- z_stream strm;
- memset(&strm, 0, sizeof(strm));
- strm.next_in = (Bytef *)compressedBytes.data();
- strm.avail_in = compressedBytes.size();
-
- bool done = false;
-
- if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK)
- {
- return false;
- }
-
- int err = Z_OK;
-
- while (!done)
- {
- // If our output buffer is too small
- if (strm.total_out >= uncompLength)
- {
- uncompressedBytes.resize(uncompLength * 2);
- uncompLength *= 2;
- }
-
- strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out);
- strm.avail_out = uncompLength - strm.total_out;
-
- // Inflate another chunk.
- err = inflate(&strm, Z_SYNC_FLUSH);
- if (err == Z_STREAM_END)
- done = true;
- else if (err != Z_OK)
- {
- break;
- }
- }
-
- if (inflateEnd(&strm) != Z_OK || !done)
- {
- return false;
- }
-
- uncompressedBytes.resize(strm.total_out);
- return true;
-}
-
-bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
-{
- if (uncompressedBytes.size() == 0)
- {
- compressedBytes = uncompressedBytes;
- return true;
- }
-
- unsigned compLength = std::min(uncompressedBytes.size(), 16);
- compressedBytes.clear();
- compressedBytes.resize(compLength);
-
- z_stream zs;
- memset(&zs, 0, sizeof(zs));
-
- if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK)
- {
- return false;
- }
-
- zs.next_in = (Bytef*)uncompressedBytes.data();
- zs.avail_in = uncompressedBytes.size();
-
- int ret;
- compressedBytes.resize(uncompressedBytes.size());
-
- unsigned offset = 0;
- unsigned temp = 0;
- do
- {
- auto remaining = compressedBytes.size() - offset;
- if(remaining < 1)
- {
- compressedBytes.resize(compressedBytes.size() * 2);
- }
- zs.next_out = (Bytef *) (compressedBytes.data() + offset);
- temp = zs.avail_out = compressedBytes.size() - offset;
- ret = deflate(&zs, Z_FINISH);
- offset += temp - zs.avail_out;
- } while (ret == Z_OK);
-
- compressedBytes.resize(offset);
-
- if (deflateEnd(&zs) != Z_OK)
- {
- return false;
- }
-
- if (ret != Z_STREAM_END)
- {
- return false;
- }
- return true;
-} \ No newline at end of file
diff --git a/libraries/logic/GZip.h b/libraries/logic/GZip.h
deleted file mode 100644
index 6993a222..00000000
--- a/libraries/logic/GZip.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-#include <QByteArray>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT GZip
-{
-public:
- static bool unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes);
- static bool zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes);
-};
-
diff --git a/libraries/logic/InstanceList.cpp b/libraries/logic/InstanceList.cpp
deleted file mode 100644
index 783df660..00000000
--- a/libraries/logic/InstanceList.cpp
+++ /dev/null
@@ -1,580 +0,0 @@
-/* Copyright 2013-2015 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 <QDir>
-#include <QSet>
-#include <QFile>
-#include <QDirIterator>
-#include <QThread>
-#include <QTextStream>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QXmlStreamReader>
-#include <QRegularExpression>
-#include <QDebug>
-
-#include "InstanceList.h"
-#include "BaseInstance.h"
-
-//FIXME: this really doesn't belong *here*
-#include "minecraft/onesix/OneSixInstance.h"
-#include "minecraft/legacy/LegacyInstance.h"
-#include "minecraft/ftb/FTBPlugin.h"
-#include "minecraft/MinecraftVersion.h"
-#include "settings/INISettingsObject.h"
-#include "NullInstance.h"
-#include "FileSystem.h"
-#include "pathmatcher/RegexpMatcher.h"
-
-const static int GROUP_FILE_FORMAT_VERSION = 1;
-
-InstanceList::InstanceList(SettingsObjectPtr globalSettings, const QString &instDir, QObject *parent)
- : QAbstractListModel(parent), m_instDir(instDir)
-{
- m_globalSettings = globalSettings;
- if (!QDir::current().exists(m_instDir))
- {
- QDir::current().mkpath(m_instDir);
- }
-}
-
-InstanceList::~InstanceList()
-{
-}
-
-int InstanceList::rowCount(const QModelIndex &parent) const
-{
- Q_UNUSED(parent);
- return m_instances.count();
-}
-
-QModelIndex InstanceList::index(int row, int column, const QModelIndex &parent) const
-{
- Q_UNUSED(parent);
- if (row < 0 || row >= m_instances.size())
- return QModelIndex();
- return createIndex(row, column, (void *)m_instances.at(row).get());
-}
-
-QVariant InstanceList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- {
- return QVariant();
- }
- BaseInstance *pdata = static_cast<BaseInstance *>(index.internalPointer());
- switch (role)
- {
- case InstancePointerRole:
- {
- QVariant v = qVariantFromValue((void *)pdata);
- return v;
- }
- case InstanceIDRole:
- {
- return pdata->id();
- }
- case Qt::DisplayRole:
- {
- return pdata->name();
- }
- case Qt::ToolTipRole:
- {
- return pdata->instanceRoot();
- }
- case Qt::DecorationRole:
- {
- return pdata->iconKey();
- }
- // HACK: see GroupView.h in gui!
- case GroupRole:
- {
- return pdata->group();
- }
- default:
- break;
- }
- return QVariant();
-}
-
-Qt::ItemFlags InstanceList::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags f;
- if (index.isValid())
- {
- f |= (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- }
- return f;
-}
-
-void InstanceList::groupChanged()
-{
- // save the groups. save all of them.
- saveGroupList();
-}
-
-QStringList InstanceList::getGroups()
-{
- return m_groups.toList();
-}
-
-void InstanceList::suspendGroupSaving()
-{
- suspendedGroupSave = true;
-}
-
-void InstanceList::resumeGroupSaving()
-{
- if(suspendedGroupSave)
- {
- suspendedGroupSave = false;
- if(queuedGroupSave)
- {
- saveGroupList();
- }
- }
-}
-
-void InstanceList::deleteGroup(const QString& name)
-{
- for(auto & instance: m_instances)
- {
- auto instGroupName = instance->group();
- if(instGroupName == name)
- {
- instance->setGroupPost(QString());
- }
- }
-}
-
-void InstanceList::saveGroupList()
-{
- if(suspendedGroupSave)
- {
- queuedGroupSave = true;
- return;
- }
-
- QString groupFileName = m_instDir + "/instgroups.json";
- QMap<QString, QSet<QString>> groupMap;
- for (auto instance : m_instances)
- {
- QString id = instance->id();
- QString group = instance->group();
- if (group.isEmpty())
- continue;
-
- // keep a list/set of groups for choosing
- m_groups.insert(group);
-
- if (!groupMap.count(group))
- {
- QSet<QString> set;
- set.insert(id);
- groupMap[group] = set;
- }
- else
- {
- QSet<QString> &set = groupMap[group];
- set.insert(id);
- }
- }
- QJsonObject toplevel;
- toplevel.insert("formatVersion", QJsonValue(QString("1")));
- QJsonObject groupsArr;
- for (auto iter = groupMap.begin(); iter != groupMap.end(); iter++)
- {
- auto list = iter.value();
- auto name = iter.key();
- QJsonObject groupObj;
- QJsonArray instanceArr;
- groupObj.insert("hidden", QJsonValue(QString("false")));
- for (auto item : list)
- {
- instanceArr.append(QJsonValue(item));
- }
- groupObj.insert("instances", instanceArr);
- groupsArr.insert(name, groupObj);
- }
- toplevel.insert("groups", groupsArr);
- QJsonDocument doc(toplevel);
- try
- {
- FS::write(groupFileName, doc.toJson());
- }
- catch(FS::FileSystemException & e)
- {
- qCritical() << "Failed to write instance group file :" << e.cause();
- }
-}
-
-void InstanceList::loadGroupList(QMap<QString, QString> &groupMap)
-{
- QString groupFileName = m_instDir + "/instgroups.json";
-
- // if there's no group file, fail
- if (!QFileInfo(groupFileName).exists())
- return;
-
- QByteArray jsonData;
- try
- {
- jsonData = FS::read(groupFileName);
- }
- catch (FS::FileSystemException & e)
- {
- qCritical() << "Failed to read instance group file :" << e.cause();
- return;
- }
-
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &error);
-
- // if the json was bad, fail
- if (error.error != QJsonParseError::NoError)
- {
- qCritical() << QString("Failed to parse instance group file: %1 at offset %2")
- .arg(error.errorString(), QString::number(error.offset))
- .toUtf8();
- return;
- }
-
- // if the root of the json wasn't an object, fail
- if (!jsonDoc.isObject())
- {
- qWarning() << "Invalid group file. Root entry should be an object.";
- return;
- }
-
- QJsonObject rootObj = jsonDoc.object();
-
- // Make sure the format version matches, otherwise fail.
- if (rootObj.value("formatVersion").toVariant().toInt() != GROUP_FILE_FORMAT_VERSION)
- return;
-
- // Get the groups. if it's not an object, fail
- if (!rootObj.value("groups").isObject())
- {
- qWarning() << "Invalid group list JSON: 'groups' should be an object.";
- return;
- }
-
- // Iterate through all the groups.
- QJsonObject groupMapping = rootObj.value("groups").toObject();
- for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++)
- {
- QString groupName = iter.key();
-
- // If not an object, complain and skip to the next one.
- if (!iter.value().isObject())
- {
- qWarning() << QString("Group '%1' in the group list should "
- "be an object.")
- .arg(groupName)
- .toUtf8();
- continue;
- }
-
- QJsonObject groupObj = iter.value().toObject();
- if (!groupObj.value("instances").isArray())
- {
- qWarning() << QString("Group '%1' in the group list is invalid. "
- "It should contain an array "
- "called 'instances'.")
- .arg(groupName)
- .toUtf8();
- continue;
- }
-
- // keep a list/set of groups for choosing
- m_groups.insert(groupName);
-
- // Iterate through the list of instances in the group.
- QJsonArray instancesArray = groupObj.value("instances").toArray();
-
- for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end();
- iter2++)
- {
- groupMap[(*iter2).toString()] = groupName;
- }
- }
-}
-
-InstanceList::InstListError InstanceList::loadList()
-{
- // load the instance groups
- QMap<QString, QString> groupMap;
- loadGroupList(groupMap);
-
- QList<InstancePtr> tempList;
- {
- QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable,
- QDirIterator::FollowSymlinks);
- while (iter.hasNext())
- {
- QString subDir = iter.next();
- if (!QFileInfo(FS::PathCombine(subDir, "instance.cfg")).exists())
- continue;
- qDebug() << "Loading MultiMC instance from " << subDir;
- InstancePtr instPtr;
- auto error = loadInstance(instPtr, subDir);
- if(!continueProcessInstance(instPtr, error, subDir, groupMap))
- continue;
- tempList.append(instPtr);
- }
- }
-
- // FIXME: generalize
- FTBPlugin::loadInstances(m_globalSettings, groupMap, tempList);
-
- beginResetModel();
- m_instances.clear();
- for(auto inst: tempList)
- {
- inst->setParent(this);
- connect(inst.get(), SIGNAL(propertiesChanged(BaseInstance *)), this,
- SLOT(propertiesChanged(BaseInstance *)));
- connect(inst.get(), SIGNAL(groupChanged()), this, SLOT(groupChanged()));
- connect(inst.get(), SIGNAL(nuked(BaseInstance *)), this,
- SLOT(instanceNuked(BaseInstance *)));
- m_instances.append(inst);
- }
- endResetModel();
- emit dataIsInvalid();
- return NoError;
-}
-
-/// Clear all instances. Triggers notifications.
-void InstanceList::clear()
-{
- beginResetModel();
- saveGroupList();
- m_instances.clear();
- endResetModel();
- emit dataIsInvalid();
-}
-
-void InstanceList::on_InstFolderChanged(const Setting &setting, QVariant value)
-{
- m_instDir = value.toString();
- loadList();
-}
-
-/// Add an instance. Triggers notifications, returns the new index
-int InstanceList::add(InstancePtr t)
-{
- beginInsertRows(QModelIndex(), m_instances.size(), m_instances.size());
- m_instances.append(t);
- t->setParent(this);
- connect(t.get(), SIGNAL(propertiesChanged(BaseInstance *)), this,
- SLOT(propertiesChanged(BaseInstance *)));
- connect(t.get(), SIGNAL(groupChanged()), this, SLOT(groupChanged()));
- connect(t.get(), SIGNAL(nuked(BaseInstance *)), this, SLOT(instanceNuked(BaseInstance *)));
- endInsertRows();
- return count() - 1;
-}
-
-InstancePtr InstanceList::getInstanceById(QString instId) const
-{
- if(instId.isEmpty())
- return InstancePtr();
- for(auto & inst: m_instances)
- {
- if (inst->id() == instId)
- {
- return inst;
- }
- }
- return InstancePtr();
-}
-
-QModelIndex InstanceList::getInstanceIndexById(const QString &id) const
-{
- return index(getInstIndex(getInstanceById(id).get()));
-}
-
-int InstanceList::getInstIndex(BaseInstance *inst) const
-{
- int count = m_instances.count();
- for (int i = 0; i < count; i++)
- {
- if (inst == m_instances[i].get())
- {
- return i;
- }
- }
- return -1;
-}
-
-bool InstanceList::continueProcessInstance(InstancePtr instPtr, const int error,
- const QDir &dir, QMap<QString, QString> &groupMap)
-{
- if (error != InstanceList::NoLoadError && error != InstanceList::NotAnInstance)
- {
- QString errorMsg = QString("Failed to load instance %1: ")
- .arg(QFileInfo(dir.absolutePath()).baseName())
- .toUtf8();
-
- switch (error)
- {
- default:
- errorMsg += QString("Unknown instance loader error %1").arg(error);
- break;
- }
- qCritical() << errorMsg.toUtf8();
- return false;
- }
- else if (!instPtr)
- {
- qCritical() << QString("Error loading instance %1. Instance loader returned null.")
- .arg(QFileInfo(dir.absolutePath()).baseName())
- .toUtf8();
- return false;
- }
- else
- {
- auto iter = groupMap.find(instPtr->id());
- if (iter != groupMap.end())
- {
- instPtr->setGroupInitial((*iter));
- }
- qDebug() << "Loaded instance " << instPtr->name() << " from " << dir.absolutePath();
- return true;
- }
-}
-
-InstanceList::InstLoadError
-InstanceList::loadInstance(InstancePtr &inst, const QString &instDir)
-{
- auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instDir, "instance.cfg"));
-
- instanceSettings->registerSetting("InstanceType", "Legacy");
-
- QString inst_type = instanceSettings->get("InstanceType").toString();
-
- // FIXME: replace with a map lookup, where instance classes register their types
- if (inst_type == "OneSix" || inst_type == "Nostalgia")
- {
- inst.reset(new OneSixInstance(m_globalSettings, instanceSettings, instDir));
- }
- else if (inst_type == "Legacy")
- {
- inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instDir));
- }
- else
- {
- inst.reset(new NullInstance(m_globalSettings, instanceSettings, instDir));
- }
- inst->init();
- return NoLoadError;
-}
-
-InstanceList::InstCreateError
-InstanceList::createInstance(InstancePtr &inst, BaseVersionPtr version, const QString &instDir)
-{
- QDir rootDir(instDir);
-
- qDebug() << instDir.toUtf8();
- if (!rootDir.exists() && !rootDir.mkpath("."))
- {
- qCritical() << "Can't create instance folder" << instDir;
- return InstanceList::CantCreateDir;
- }
-
- if (!version)
- {
- qCritical() << "Can't create instance for non-existing MC version";
- return InstanceList::NoSuchVersion;
- }
-
- auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instDir, "instance.cfg"));
- instanceSettings->registerSetting("InstanceType", "Legacy");
-
- auto minecraftVersion = std::dynamic_pointer_cast<MinecraftVersion>(version);
- if(minecraftVersion)
- {
- auto mcVer = std::dynamic_pointer_cast<MinecraftVersion>(version);
- instanceSettings->set("InstanceType", "OneSix");
- inst.reset(new OneSixInstance(m_globalSettings, instanceSettings, instDir));
- inst->setIntendedVersionId(version->descriptor());
- inst->init();
- return InstanceList::NoCreateError;
- }
- return InstanceList::NoSuchVersion;
-}
-
-InstanceList::InstCreateError
-InstanceList::copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance, const QString &instDir, bool copySaves)
-{
- QDir rootDir(instDir);
- std::unique_ptr<IPathMatcher> matcher;
- if(!copySaves)
- {
- auto matcherReal = new RegexpMatcher("[.]?minecraft/saves");
- matcherReal->caseSensitive(false);
- matcher.reset(matcherReal);
- }
-
- qDebug() << instDir.toUtf8();
- FS::copy folderCopy(oldInstance->instanceRoot(), instDir);
- folderCopy.followSymlinks(false).blacklist(matcher.get());
- if (!folderCopy())
- {
- FS::deletePath(instDir);
- return InstanceList::CantCreateDir;
- }
-
- INISettingsObject settings_obj(FS::PathCombine(instDir, "instance.cfg"));
- settings_obj.registerSetting("InstanceType", "Legacy");
- QString inst_type = settings_obj.get("InstanceType").toString();
-
- oldInstance->copy(instDir);
-
- auto error = loadInstance(newInstance, instDir);
-
- switch (error)
- {
- case NoLoadError:
- return NoCreateError;
- case NotAnInstance:
- rootDir.removeRecursively();
- return CantCreateDir;
- default:
- case UnknownLoadError:
- rootDir.removeRecursively();
- return UnknownCreateError;
- }
-}
-
-void InstanceList::instanceNuked(BaseInstance *inst)
-{
- int i = getInstIndex(inst);
- if (i != -1)
- {
- beginRemoveRows(QModelIndex(), i, i);
- m_instances.removeAt(i);
- endRemoveRows();
- }
-}
-
-void InstanceList::propertiesChanged(BaseInstance *inst)
-{
- int i = getInstIndex(inst);
- if (i != -1)
- {
- emit dataChanged(index(i), index(i));
- }
-}
diff --git a/libraries/logic/InstanceList.h b/libraries/logic/InstanceList.h
deleted file mode 100644
index 074cca7c..00000000
--- a/libraries/logic/InstanceList.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QAbstractListModel>
-#include <QSet>
-
-#include "BaseInstance.h"
-
-#include "multimc_logic_export.h"
-
-class BaseInstance;
-class QDir;
-
-class MULTIMC_LOGIC_EXPORT InstanceList : public QAbstractListModel
-{
- Q_OBJECT
-private:
- void loadGroupList(QMap<QString, QString> &groupList);
- void suspendGroupSaving();
- void resumeGroupSaving();
-
-public slots:
- void saveGroupList();
-
-public:
- explicit InstanceList(SettingsObjectPtr globalSettings, const QString &instDir, QObject *parent = 0);
- virtual ~InstanceList();
-
-public:
- QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- enum AdditionalRoles
- {
- GroupRole = Qt::UserRole,
- InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance
- InstanceIDRole = 0x34B1CB49 ///< Return id if the instance
- };
- /*!
- * \brief Error codes returned by functions in the InstanceList class.
- * NoError Indicates that no error occurred.
- * UnknownError indicates that an unspecified error occurred.
- */
- enum InstListError
- {
- NoError = 0,
- UnknownError
- };
-
- enum InstLoadError
- {
- NoLoadError = 0,
- UnknownLoadError,
- NotAnInstance
- };
-
- enum InstCreateError
- {
- NoCreateError = 0,
- NoSuchVersion,
- UnknownCreateError,
- InstExists,
- CantCreateDir
- };
-
- QString instDir() const
- {
- return m_instDir;
- }
-
- /*!
- * \brief Get the instance at index
- */
- InstancePtr at(int i) const
- {
- return m_instances.at(i);
- }
- ;
-
- /*!
- * \brief Get the count of loaded instances
- */
- int count() const
- {
- return m_instances.count();
- }
- ;
-
- /// Clear all instances. Triggers notifications.
- void clear();
-
- /// Add an instance. Triggers notifications, returns the new index
- int add(InstancePtr t);
-
- /// Get an instance by ID
- InstancePtr getInstanceById(QString id) const;
-
- QModelIndex getInstanceIndexById(const QString &id) const;
-
- // FIXME: instead of iterating through all instances and forming a set, keep the set around
- QStringList getGroups();
-
- void deleteGroup(const QString & name);
-
- /*!
- * \brief Creates a stub instance
- *
- * \param inst Pointer to store the created instance in.
- * \param version Game version to use for the instance
- * \param instDir The new instance's directory.
- * \return An InstCreateError error code.
- * - InstExists if the given instance directory is already an instance.
- * - CantCreateDir if the given instance directory cannot be created.
- */
- InstCreateError createInstance(InstancePtr &inst, BaseVersionPtr version,
- const QString &instDir);
-
- /*!
- * \brief Creates a copy of an existing instance with a new name
- *
- * \param newInstance Pointer to store the created instance in.
- * \param oldInstance The instance to copy
- * \param instDir The new instance's directory.
- * \return An InstCreateError error code.
- * - InstExists if the given instance directory is already an instance.
- * - CantCreateDir if the given instance directory cannot be created.
- */
- InstCreateError copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance,
- const QString &instDir, bool copySaves);
-
- /*!
- * \brief Loads an instance from the given directory.
- * Checks the instance's INI file to figure out what the instance's type is first.
- * \param inst Pointer to store the loaded instance in.
- * \param instDir The instance's directory.
- * \return An InstLoadError error code.
- * - NotAnInstance if the given instance directory isn't a valid instance.
- */
- InstLoadError loadInstance(InstancePtr &inst, const QString &instDir);
-
-signals:
- void dataIsInvalid();
-
-public slots:
- void on_InstFolderChanged(const Setting &setting, QVariant value);
-
- /*!
- * \brief Loads the instance list. Triggers notifications.
- */
- InstListError loadList();
-
-private slots:
- void propertiesChanged(BaseInstance *inst);
- void instanceNuked(BaseInstance *inst);
- void groupChanged();
-
-private:
- int getInstIndex(BaseInstance *inst) const;
-
-public:
- static bool continueProcessInstance(InstancePtr instPtr, const int error, const QDir &dir, QMap<QString, QString> &groupMap);
-
-protected:
- QString m_instDir;
- QList<InstancePtr> m_instances;
- QSet<QString> m_groups;
- SettingsObjectPtr m_globalSettings;
- bool suspendedGroupSave = false;
- bool queuedGroupSave = false;
-};
diff --git a/libraries/logic/Json.cpp b/libraries/logic/Json.cpp
deleted file mode 100644
index f2cbc8a3..00000000
--- a/libraries/logic/Json.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-// Licensed under the Apache-2.0 license. See README.md for details.
-
-#include "Json.h"
-
-#include <QFile>
-
-#include "FileSystem.h"
-#include <math.h>
-
-namespace Json
-{
-void write(const QJsonDocument &doc, const QString &filename)
-{
- FS::write(filename, doc.toJson());
-}
-void write(const QJsonObject &object, const QString &filename)
-{
- write(QJsonDocument(object), filename);
-}
-void write(const QJsonArray &array, const QString &filename)
-{
- write(QJsonDocument(array), filename);
-}
-
-QByteArray toBinary(const QJsonObject &obj)
-{
- return QJsonDocument(obj).toBinaryData();
-}
-QByteArray toBinary(const QJsonArray &array)
-{
- return QJsonDocument(array).toBinaryData();
-}
-QByteArray toText(const QJsonObject &obj)
-{
- return QJsonDocument(obj).toJson(QJsonDocument::Compact);
-}
-QByteArray toText(const QJsonArray &array)
-{
- return QJsonDocument(array).toJson(QJsonDocument::Compact);
-}
-
-static bool isBinaryJson(const QByteArray &data)
-{
- decltype(QJsonDocument::BinaryFormatTag) tag = QJsonDocument::BinaryFormatTag;
- return memcmp(data.constData(), &tag, sizeof(QJsonDocument::BinaryFormatTag)) == 0;
-}
-QJsonDocument requireDocument(const QByteArray &data, const QString &what)
-{
- if (isBinaryJson(data))
- {
- QJsonDocument doc = QJsonDocument::fromBinaryData(data);
- if (doc.isNull())
- {
- throw JsonException(what + ": Invalid JSON (binary JSON detected)");
- }
- return doc;
- }
- else
- {
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(data, &error);
- if (error.error != QJsonParseError::NoError)
- {
- throw JsonException(what + ": Error parsing JSON: " + error.errorString());
- }
- return doc;
- }
-}
-QJsonDocument requireDocument(const QString &filename, const QString &what)
-{
- return requireDocument(FS::read(filename), what);
-}
-QJsonObject requireObject(const QJsonDocument &doc, const QString &what)
-{
- if (!doc.isObject())
- {
- throw JsonException(what + " is not an object");
- }
- return doc.object();
-}
-QJsonArray requireArray(const QJsonDocument &doc, const QString &what)
-{
- if (!doc.isArray())
- {
- throw JsonException(what + " is not an array");
- }
- return doc.array();
-}
-
-void writeString(QJsonObject &to, const QString &key, const QString &value)
-{
- if (!value.isEmpty())
- {
- to.insert(key, value);
- }
-}
-
-void writeStringList(QJsonObject &to, const QString &key, const QStringList &values)
-{
- if (!values.isEmpty())
- {
- QJsonArray array;
- for(auto value: values)
- {
- array.append(value);
- }
- to.insert(key, array);
- }
-}
-
-template<>
-QJsonValue toJson<QUrl>(const QUrl &url)
-{
- return QJsonValue(url.toString(QUrl::FullyEncoded));
-}
-template<>
-QJsonValue toJson<QByteArray>(const QByteArray &data)
-{
- return QJsonValue(QString::fromLatin1(data.toHex()));
-}
-template<>
-QJsonValue toJson<QDateTime>(const QDateTime &datetime)
-{
- return QJsonValue(datetime.toString(Qt::ISODate));
-}
-template<>
-QJsonValue toJson<QDir>(const QDir &dir)
-{
- return QDir::current().relativeFilePath(dir.absolutePath());
-}
-template<>
-QJsonValue toJson<QUuid>(const QUuid &uuid)
-{
- return uuid.toString();
-}
-template<>
-QJsonValue toJson<QVariant>(const QVariant &variant)
-{
- return QJsonValue::fromVariant(variant);
-}
-
-
-template<> QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what)
-{
- const QString string = ensureIsType<QString>(value, what);
- // ensure that the string can be safely cast to Latin1
- if (string != QString::fromLatin1(string.toLatin1()))
- {
- throw JsonException(what + " is not encodable as Latin1");
- }
- return QByteArray::fromHex(string.toLatin1());
-}
-
-template<> QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what)
-{
- if (!value.isArray())
- {
- throw JsonException(what + " is not an array");
- }
- return value.toArray();
-}
-
-
-template<> QString requireIsType<QString>(const QJsonValue &value, const QString &what)
-{
- if (!value.isString())
- {
- throw JsonException(what + " is not a string");
- }
- return value.toString();
-}
-
-template<> bool requireIsType<bool>(const QJsonValue &value, const QString &what)
-{
- if (!value.isBool())
- {
- throw JsonException(what + " is not a bool");
- }
- return value.toBool();
-}
-
-template<> double requireIsType<double>(const QJsonValue &value, const QString &what)
-{
- if (!value.isDouble())
- {
- throw JsonException(what + " is not a double");
- }
- return value.toDouble();
-}
-
-template<> int requireIsType<int>(const QJsonValue &value, const QString &what)
-{
- const double doubl = requireIsType<double>(value, what);
- if (fmod(doubl, 1) != 0)
- {
- throw JsonException(what + " is not an integer");
- }
- return int(doubl);
-}
-
-template<> QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what)
-{
- const QString string = requireIsType<QString>(value, what);
- const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate);
- if (!datetime.isValid())
- {
- throw JsonException(what + " is not a ISO formatted date/time value");
- }
- return datetime;
-}
-
-template<> QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what)
-{
- const QString string = ensureIsType<QString>(value, what);
- if (string.isEmpty())
- {
- return QUrl();
- }
- const QUrl url = QUrl(string, QUrl::StrictMode);
- if (!url.isValid())
- {
- throw JsonException(what + " is not a correctly formatted URL");
- }
- return url;
-}
-
-template<> QDir requireIsType<QDir>(const QJsonValue &value, const QString &what)
-{
- const QString string = requireIsType<QString>(value, what);
- // FIXME: does not handle invalid characters!
- return QDir::current().absoluteFilePath(string);
-}
-
-template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what)
-{
- const QString string = requireIsType<QString>(value, what);
- const QUuid uuid = QUuid(string);
- if (uuid.toString() != string) // converts back => valid
- {
- throw JsonException(what + " is not a valid UUID");
- }
- return uuid;
-}
-
-template<> QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what)
-{
- if (!value.isObject())
- {
- throw JsonException(what + " is not an object");
- }
- return value.toObject();
-}
-
-template<> QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what)
-{
- if (value.isNull() || value.isUndefined())
- {
- throw JsonException(what + " is null or undefined");
- }
- return value.toVariant();
-}
-
-template<> QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what)
-{
- if (value.isNull() || value.isUndefined())
- {
- throw JsonException(what + " is null or undefined");
- }
- return value;
-}
-
-}
diff --git a/libraries/logic/Json.h b/libraries/logic/Json.h
deleted file mode 100644
index 2cb60f0e..00000000
--- a/libraries/logic/Json.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// Licensed under the Apache-2.0 license. See README.md for details.
-
-#pragma once
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QJsonObject>
-#include <QDateTime>
-#include <QUrl>
-#include <QDir>
-#include <QUuid>
-#include <QVariant>
-#include <memory>
-
-#include "Exception.h"
-
-namespace Json
-{
-class MULTIMC_LOGIC_EXPORT JsonException : public ::Exception
-{
-public:
- JsonException(const QString &message) : Exception(message) {}
-};
-
-/// @throw FileSystemException
-void write(const QJsonDocument &doc, const QString &filename);
-/// @throw FileSystemException
-void write(const QJsonObject &object, const QString &filename);
-/// @throw FileSystemException
-void write(const QJsonArray &array, const QString &filename);
-
-QByteArray toBinary(const QJsonObject &obj);
-QByteArray toBinary(const QJsonArray &array);
-QByteArray toText(const QJsonObject &obj);
-QByteArray toText(const QJsonArray &array);
-
-/// @throw JsonException
-MULTIMC_LOGIC_EXPORT QJsonDocument requireDocument(const QByteArray &data, const QString &what = "Document");
-/// @throw JsonException
-MULTIMC_LOGIC_EXPORT QJsonDocument requireDocument(const QString &filename, const QString &what = "Document");
-/// @throw JsonException
-MULTIMC_LOGIC_EXPORT QJsonObject requireObject(const QJsonDocument &doc, const QString &what = "Document");
-/// @throw JsonException
-MULTIMC_LOGIC_EXPORT QJsonArray requireArray(const QJsonDocument &doc, const QString &what = "Document");
-
-/////////////////// WRITING ////////////////////
-
-void writeString(QJsonObject & to, const QString &key, const QString &value);
-void writeStringList(QJsonObject & to, const QString &key, const QStringList &values);
-
-template<typename T>
-QJsonValue toJson(const T &t)
-{
- return QJsonValue(t);
-}
-template<>
-QJsonValue toJson<QUrl>(const QUrl &url);
-template<>
-QJsonValue toJson<QByteArray>(const QByteArray &data);
-template<>
-QJsonValue toJson<QDateTime>(const QDateTime &datetime);
-template<>
-QJsonValue toJson<QDir>(const QDir &dir);
-template<>
-QJsonValue toJson<QUuid>(const QUuid &uuid);
-template<>
-QJsonValue toJson<QVariant>(const QVariant &variant);
-
-template<typename T>
-QJsonArray toJsonArray(const QList<T> &container)
-{
- QJsonArray array;
- for (const T item : container)
- {
- array.append(toJson<T>(item));
- }
- return array;
-}
-
-////////////////// READING ////////////////////
-
-/// @throw JsonException
-template <typename T>
-T requireIsType(const QJsonValue &value, const QString &what = "Value");
-
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT double requireIsType<double>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT bool requireIsType<bool>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT int requireIsType<int>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QString requireIsType<QString>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QDir requireIsType<QDir>(const QJsonValue &value, const QString &what);
-/// @throw JsonException
-template<> MULTIMC_LOGIC_EXPORT QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what);
-
-// the following functions are higher level functions, that make use of the above functions for
-// type conversion
-template <typename T>
-T ensureIsType(const QJsonValue &value, const T default_ = T(), const QString &what = "Value")
-{
- if (value.isUndefined() || value.isNull())
- {
- return default_;
- }
- try
- {
- return requireIsType<T>(value, what);
- }
- catch (JsonException &)
- {
- return default_;
- }
-}
-
-/// @throw JsonException
-template <typename T>
-T requireIsType(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__")
-{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- throw JsonException(localWhat + "s parent does not contain " + localWhat);
- }
- return requireIsType<T>(parent.value(key), localWhat);
-}
-
-template <typename T>
-T ensureIsType(const QJsonObject &parent, const QString &key, const T default_ = T(), const QString &what = "__placeholder__")
-{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- return default_;
- }
- return ensureIsType<T>(parent.value(key), default_, localWhat);
-}
-
-template <typename T>
-QVector<T> requireIsArrayOf(const QJsonDocument &doc)
-{
- const QJsonArray array = requireArray(doc);
- QVector<T> out;
- for (const QJsonValue val : array)
- {
- out.append(requireIsType<T>(val, "Document"));
- }
- return out;
-}
-
-template <typename T>
-QVector<T> ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value")
-{
- const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what);
- QVector<T> out;
- for (const QJsonValue val : array)
- {
- out.append(requireIsType<T>(val, what));
- }
- return out;
-}
-
-template <typename T>
-QVector<T> ensureIsArrayOf(const QJsonValue &value, const QVector<T> default_, const QString &what = "Value")
-{
- if (value.isUndefined())
- {
- return default_;
- }
- return ensureIsArrayOf<T>(value, what);
-}
-
-/// @throw JsonException
-template <typename T>
-QVector<T> requireIsArrayOf(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__")
-{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- throw JsonException(localWhat + "s parent does not contain " + localWhat);
- }
- return ensureIsArrayOf<T>(parent.value(key), localWhat);
-}
-
-template <typename T>
-QVector<T> ensureIsArrayOf(const QJsonObject &parent, const QString &key,
- const QVector<T> &default_ = QVector<T>(), const QString &what = "__placeholder__")
-{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- return default_;
- }
- return ensureIsArrayOf<T>(parent.value(key), default_, localWhat);
-}
-
-// this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers
-#define JSON_HELPERFUNCTIONS(NAME, TYPE) \
- inline TYPE require##NAME(const QJsonValue &value, const QString &what = "Value") \
- { \
- return requireIsType<TYPE>(value, what); \
- } \
- inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_ = TYPE(), const QString &what = "Value") \
- { \
- return ensureIsType<TYPE>(value, default_, what); \
- } \
- inline TYPE require##NAME(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") \
- { \
- return requireIsType<TYPE>(parent, key, what); \
- } \
- inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_ = TYPE(), const QString &what = "__placeholder") \
- { \
- return ensureIsType<TYPE>(parent, key, default_, what); \
- }
-
-JSON_HELPERFUNCTIONS(Array, QJsonArray)
-JSON_HELPERFUNCTIONS(Object, QJsonObject)
-JSON_HELPERFUNCTIONS(JsonValue, QJsonValue)
-JSON_HELPERFUNCTIONS(String, QString)
-JSON_HELPERFUNCTIONS(Boolean, bool)
-JSON_HELPERFUNCTIONS(Double, double)
-JSON_HELPERFUNCTIONS(Integer, int)
-JSON_HELPERFUNCTIONS(DateTime, QDateTime)
-JSON_HELPERFUNCTIONS(Url, QUrl)
-JSON_HELPERFUNCTIONS(ByteArray, QByteArray)
-JSON_HELPERFUNCTIONS(Dir, QDir)
-JSON_HELPERFUNCTIONS(Uuid, QUuid)
-JSON_HELPERFUNCTIONS(Variant, QVariant)
-
-#undef JSON_HELPERFUNCTIONS
-
-}
-using JSONValidationError = Json::JsonException;
diff --git a/libraries/logic/MMCStrings.cpp b/libraries/logic/MMCStrings.cpp
deleted file mode 100644
index c50d596e..00000000
--- a/libraries/logic/MMCStrings.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "MMCStrings.h"
-
-/// TAKEN FROM Qt, because it doesn't expose it intelligently
-static inline QChar getNextChar(const QString &s, int location)
-{
- return (location < s.length()) ? s.at(location) : QChar();
-}
-
-/// TAKEN FROM Qt, because it doesn't expose it intelligently
-int Strings::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
-{
- for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2)
- {
- // skip spaces, tabs and 0's
- QChar c1 = getNextChar(s1, l1);
- while (c1.isSpace())
- c1 = getNextChar(s1, ++l1);
- QChar c2 = getNextChar(s2, l2);
- while (c2.isSpace())
- c2 = getNextChar(s2, ++l2);
-
- if (c1.isDigit() && c2.isDigit())
- {
- while (c1.digitValue() == 0)
- c1 = getNextChar(s1, ++l1);
- while (c2.digitValue() == 0)
- c2 = getNextChar(s2, ++l2);
-
- int lookAheadLocation1 = l1;
- int lookAheadLocation2 = l2;
- int currentReturnValue = 0;
- // find the last digit, setting currentReturnValue as we go if it isn't equal
- for (QChar lookAhead1 = c1, lookAhead2 = c2;
- (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length());
- lookAhead1 = getNextChar(s1, ++lookAheadLocation1),
- lookAhead2 = getNextChar(s2, ++lookAheadLocation2))
- {
- bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit();
- bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit();
- if (!is1ADigit && !is2ADigit)
- break;
- if (!is1ADigit)
- return -1;
- if (!is2ADigit)
- return 1;
- if (currentReturnValue == 0)
- {
- if (lookAhead1 < lookAhead2)
- {
- currentReturnValue = -1;
- }
- else if (lookAhead1 > lookAhead2)
- {
- currentReturnValue = 1;
- }
- }
- }
- if (currentReturnValue != 0)
- return currentReturnValue;
- }
- if (cs == Qt::CaseInsensitive)
- {
- if (!c1.isLower())
- c1 = c1.toLower();
- if (!c2.isLower())
- c2 = c2.toLower();
- }
- int r = QString::localeAwareCompare(c1, c2);
- if (r < 0)
- return -1;
- if (r > 0)
- return 1;
- }
- // The two strings are the same (02 == 2) so fall back to the normal sort
- return QString::compare(s1, s2, cs);
-}
diff --git a/libraries/logic/MMCStrings.h b/libraries/logic/MMCStrings.h
deleted file mode 100644
index 5606b909..00000000
--- a/libraries/logic/MMCStrings.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#include <QString>
-
-#include "multimc_logic_export.h"
-
-namespace Strings
-{
- int MULTIMC_LOGIC_EXPORT naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs);
-}
diff --git a/libraries/logic/MMCZip.cpp b/libraries/logic/MMCZip.cpp
deleted file mode 100644
index 0f35bc70..00000000
--- a/libraries/logic/MMCZip.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
-Copyright (C) 2010 Roberto Pompermaier
-Copyright (C) 2005-2014 Sergey A. Tachenov
-
-Parts of this file were part of QuaZIP.
-
-QuaZIP is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 2.1 of the License, or
-(at your option) any later version.
-
-QuaZIP is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant and contributors,
-see quazip/(un)MMCZip.h files for details. Basically it's the zlib license.
-*/
-
-#include <quazip.h>
-#include <JlCompress.h>
-#include <quazipdir.h>
-#include "MMCZip.h"
-#include "FileSystem.h"
-
-#include <QDebug>
-
-bool copyData(QIODevice &inFile, QIODevice &outFile)
-{
- while (!inFile.atEnd())
- {
- char buf[4096];
- qint64 readLen = inFile.read(buf, 4096);
- if (readLen <= 0)
- return false;
- if (outFile.write(buf, readLen) != readLen)
- return false;
- }
- return true;
-}
-
-QStringList MMCZip::extractDir(QString fileCompressed, QString dir)
-{
- return JlCompress::extractDir(fileCompressed, dir);
-}
-
-bool compressFile(QuaZip *zip, QString fileName, QString fileDest)
-{
- if (!zip)
- {
- return false;
- }
- if (zip->getMode() != QuaZip::mdCreate && zip->getMode() != QuaZip::mdAppend &&
- zip->getMode() != QuaZip::mdAdd)
- {
- return false;
- }
-
- QFile inFile;
- inFile.setFileName(fileName);
- if (!inFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
-
- QuaZipFile outFile(zip);
- if (!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName())))
- {
- return false;
- }
-
- if (!copyData(inFile, outFile) || outFile.getZipError() != UNZ_OK)
- {
- return false;
- }
-
- outFile.close();
- if (outFile.getZipError() != UNZ_OK)
- {
- return false;
- }
- inFile.close();
-
- return true;
-}
-
-bool MMCZip::compressSubDir(QuaZip* zip, QString dir, QString origDir, QSet<QString>& added, QString prefix, const SeparatorPrefixTree <'/'> * blacklist)
-{
- if (!zip) return false;
- if (zip->getMode()!=QuaZip::mdCreate && zip->getMode()!=QuaZip::mdAppend && zip->getMode()!=QuaZip::mdAdd)
- {
- return false;
- }
-
- QDir directory(dir);
- if (!directory.exists())
- {
- return false;
- }
-
- QDir origDirectory(origDir);
- if (dir != origDir)
- {
- QString internalDirName = origDirectory.relativeFilePath(dir);
- if(!blacklist || !blacklist->covers(internalDirName))
- {
- QuaZipFile dirZipFile(zip);
- auto dirPrefix = FS::PathCombine(prefix, origDirectory.relativeFilePath(dir)) + "/";
- if (!dirZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(dirPrefix, dir), 0, 0, 0))
- {
- return false;
- }
- dirZipFile.close();
- }
- }
-
- QFileInfoList files = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
- for (auto file: files)
- {
- if(!file.isDir())
- {
- continue;
- }
- if(!compressSubDir(zip,file.absoluteFilePath(),origDir, added, prefix, blacklist))
- {
- return false;
- }
- }
-
- files = directory.entryInfoList(QDir::Files);
- for (auto file: files)
- {
- if(!file.isFile())
- {
- continue;
- }
-
- if(file.absoluteFilePath()==zip->getZipName())
- {
- continue;
- }
-
- QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
- if(blacklist && blacklist->covers(filename))
- {
- continue;
- }
- if(prefix.size())
- {
- filename = FS::PathCombine(prefix, filename);
- }
- added.insert(filename);
- if (!compressFile(zip,file.absoluteFilePath(),filename))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
- std::function<bool(QString)> filter)
-{
- QuaZip modZip(from.filePath());
- modZip.open(QuaZip::mdUnzip);
-
- QuaZipFile fileInsideMod(&modZip);
- QuaZipFile zipOutFile(into);
- for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
- {
- QString filename = modZip.getCurrentFileName();
- if (!filter(filename))
- {
- qDebug() << "Skipping file " << filename << " from "
- << from.fileName() << " - filtered";
- continue;
- }
- if (contained.contains(filename))
- {
- qDebug() << "Skipping already contained file " << filename << " from "
- << from.fileName();
- continue;
- }
- contained.insert(filename);
-
- if (!fileInsideMod.open(QIODevice::ReadOnly))
- {
- qCritical() << "Failed to open " << filename << " from " << from.fileName();
- return false;
- }
-
- QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
-
- if (!zipOutFile.open(QIODevice::WriteOnly, info_out))
- {
- qCritical() << "Failed to open " << filename << " in the jar";
- fileInsideMod.close();
- return false;
- }
- if (!copyData(fileInsideMod, zipOutFile))
- {
- zipOutFile.close();
- fileInsideMod.close();
- qCritical() << "Failed to copy data of " << filename << " into the jar";
- return false;
- }
- zipOutFile.close();
- fileInsideMod.close();
- }
- return true;
-}
-
-bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods)
-{
- QuaZip zipOut(targetJarPath);
- if (!zipOut.open(QuaZip::mdCreate))
- {
- QFile::remove(targetJarPath);
- qCritical() << "Failed to open the minecraft.jar for modding";
- return false;
- }
- // Files already added to the jar.
- // These files will be skipped.
- QSet<QString> addedFiles;
-
- // Modify the jar
- QListIterator<Mod> i(mods);
- i.toBack();
- while (i.hasPrevious())
- {
- const Mod &mod = i.previous();
- // do not merge disabled mods.
- if (!mod.enabled())
- continue;
- if (mod.type() == Mod::MOD_ZIPFILE)
- {
- if (!mergeZipFiles(&zipOut, mod.filename(), addedFiles, noFilter))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- }
- else if (mod.type() == Mod::MOD_SINGLEFILE)
- {
- auto filename = mod.filename();
- if (!compressFile(&zipOut, filename.absoluteFilePath(),
- filename.fileName()))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- addedFiles.insert(filename.fileName());
- }
- else if (mod.type() == Mod::MOD_FOLDER)
- {
- auto filename = mod.filename();
- QString what_to_zip = filename.absoluteFilePath();
- QDir dir(what_to_zip);
- dir.cdUp();
- QString parent_dir = dir.absolutePath();
- if (!compressSubDir(&zipOut, what_to_zip, parent_dir, addedFiles))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- qDebug() << "Adding folder " << filename.fileName() << " from "
- << filename.absoluteFilePath();
- }
- }
-
- if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, metaInfFilter))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to insert minecraft.jar contents.";
- return false;
- }
-
- // Recompress the jar
- zipOut.close();
- if (zipOut.getZipError() != 0)
- {
- QFile::remove(targetJarPath);
- qCritical() << "Failed to finalize minecraft.jar!";
- return false;
- }
- return true;
-}
-
-bool MMCZip::noFilter(QString)
-{
- return true;
-}
-
-bool MMCZip::metaInfFilter(QString key)
-{
- if(key.contains("META-INF"))
- {
- return false;
- }
- return true;
-}
-
-bool MMCZip::compressDir(QString zipFile, QString dir, QString prefix, const SeparatorPrefixTree <'/'> * blacklist)
-{
- QuaZip zip(zipFile);
- QDir().mkpath(QFileInfo(zipFile).absolutePath());
- if(!zip.open(QuaZip::mdCreate))
- {
- QFile::remove(zipFile);
- return false;
- }
-
- QSet<QString> added;
- if (!compressSubDir(&zip, dir, dir, added, prefix, blacklist))
- {
- QFile::remove(zipFile);
- return false;
- }
- zip.close();
- if(zip.getZipError()!=0)
- {
- QFile::remove(zipFile);
- return false;
- }
- return true;
-}
-
-QString MMCZip::findFileInZip(QuaZip * zip, const QString & what, const QString &root)
-{
- QuaZipDir rootDir(zip, root);
- for(auto fileName: rootDir.entryList(QDir::Files))
- {
- if(fileName == what)
- return root;
- }
- for(auto fileName: rootDir.entryList(QDir::Dirs))
- {
- QString result = findFileInZip(zip, what, root + fileName);
- if(!result.isEmpty())
- {
- return result;
- }
- }
- return QString();
-}
-
-bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root)
-{
- QuaZipDir rootDir(zip, root);
- for(auto fileName: rootDir.entryList(QDir::Files))
- {
- if(fileName == what)
- {
- result.append(root);
- return true;
- }
- }
- for(auto fileName: rootDir.entryList(QDir::Dirs))
- {
- findFilesInZip(zip, what, result, root + fileName);
- }
- return !result.isEmpty();
-}
-
-bool removeFile(QStringList listFile)
-{
- bool ret = true;
- for (int i = 0; i < listFile.count(); i++)
- {
- ret &= QFile::remove(listFile.at(i));
- }
- return ret;
-}
-
-bool MMCZip::extractFile(QuaZip *zip, const QString &fileName, const QString &fileDest)
-{
- if(!zip)
- return false;
-
- if (zip->getMode() != QuaZip::mdUnzip)
- return false;
-
- if (!fileName.isEmpty())
- zip->setCurrentFile(fileName);
-
- QuaZipFile inFile(zip);
- if (!inFile.open(QIODevice::ReadOnly) || inFile.getZipError() != UNZ_OK)
- return false;
-
- // Controllo esistenza cartella file risultato
- QDir curDir;
- if (fileDest.endsWith('/'))
- {
- if (!curDir.mkpath(fileDest))
- {
- return false;
- }
- }
- else
- {
- if (!curDir.mkpath(QFileInfo(fileDest).absolutePath()))
- {
- return false;
- }
- }
-
- QuaZipFileInfo64 info;
- if (!zip->getCurrentFileInfo(&info))
- return false;
-
- QFile::Permissions srcPerm = info.getPermissions();
- if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir())
- {
- if (srcPerm != 0)
- {
- QFile(fileDest).setPermissions(srcPerm);
- }
- return true;
- }
-
- QFile outFile;
- outFile.setFileName(fileDest);
- if (!outFile.open(QIODevice::WriteOnly))
- return false;
-
- if (!copyData(inFile, outFile) || inFile.getZipError() != UNZ_OK)
- {
- outFile.close();
- removeFile(QStringList(fileDest));
- return false;
- }
- outFile.close();
-
- inFile.close();
- if (inFile.getZipError() != UNZ_OK)
- {
- removeFile(QStringList(fileDest));
- return false;
- }
-
- if (srcPerm != 0)
- {
- outFile.setPermissions(srcPerm);
- }
- return true;
-}
-
-QStringList MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target)
-{
- QDir directory(target);
- QStringList extracted;
- if (!zip->goToFirstFile())
- {
- return QStringList();
- }
- do
- {
- QString name = zip->getCurrentFileName();
- if(!name.startsWith(subdir))
- {
- continue;
- }
- name.remove(0, subdir.size());
- QString absFilePath = directory.absoluteFilePath(name);
- if(name.isEmpty())
- {
- absFilePath += "/";
- }
- if (!extractFile(zip, "", absFilePath))
- {
- removeFile(extracted);
- return QStringList();
- }
- extracted.append(absFilePath);
- } while (zip->goToNextFile());
- return extracted;
-}
diff --git a/libraries/logic/MMCZip.h b/libraries/logic/MMCZip.h
deleted file mode 100644
index f350e668..00000000
--- a/libraries/logic/MMCZip.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QFileInfo>
-#include <QSet>
-#include "minecraft/Mod.h"
-#include "SeparatorPrefixTree.h"
-#include <functional>
-
-#include "multimc_logic_export.h"
-
-class QuaZip;
-
-namespace MMCZip
-{
- /**
- * Compress a subdirectory.
- * \param parentZip Opened zip containing the parent directory.
- * \param dir The full path to the directory to pack.
- * \param parentDir The full path to the directory corresponding to the root of the ZIP.
- * \param recursive Whether to pack sub-directories as well or only files.
- * \return true if success, false otherwise.
- */
- bool MULTIMC_LOGIC_EXPORT compressSubDir(QuaZip *zip, QString dir, QString origDir, QSet<QString> &added,
- QString prefix = QString(), const SeparatorPrefixTree <'/'> * blacklist = nullptr);
-
- /**
- * Compress a whole directory.
- * \param fileCompressed The name of the archive.
- * \param dir The directory to compress.
- * \param recursive Whether to pack the subdirectories as well, or just regular files.
- * \return true if success, false otherwise.
- */
- bool MULTIMC_LOGIC_EXPORT compressDir(QString zipFile, QString dir, QString prefix = QString(), const SeparatorPrefixTree <'/'> * blacklist = nullptr);
-
- /// filter function for @mergeZipFiles - passthrough
- bool MULTIMC_LOGIC_EXPORT noFilter(QString key);
-
- /// filter function for @mergeZipFiles - ignores METAINF
- bool MULTIMC_LOGIC_EXPORT metaInfFilter(QString key);
-
- /**
- * Merge two zip files, using a filter function
- */
- bool MULTIMC_LOGIC_EXPORT mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, std::function<bool(QString)> filter);
-
- /**
- * take a source jar, add mods to it, resulting in target jar
- */
- bool MULTIMC_LOGIC_EXPORT createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods);
-
- /**
- * Extract a whole archive.
- *
- * \param fileCompressed The name of the archive.
- * \param dir The directory to extract to, the current directory if
- * left empty.
- * \return The list of the full paths of the files extracted, empty on failure.
- */
- QStringList MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString dir = QString());
-
- /**
- * Find a single file in archive by file name (not path)
- *
- * \return the path prefix where the file is
- */
- QString MULTIMC_LOGIC_EXPORT findFileInZip(QuaZip * zip, const QString & what, const QString &root = QString());
-
- /**
- * Find a multiple files of the same name in archive by file name
- * If a file is found in a path, no deeper paths are searched
- *
- * \return true if anything was found
- */
- bool MULTIMC_LOGIC_EXPORT findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root = QString());
-
- /**
- * Extract a single file to a destination
- *
- * \return true if it succeeds
- */
- bool MULTIMC_LOGIC_EXPORT extractFile(QuaZip *zip, const QString &fileName, const QString &fileDest);
-
- /**
- * Extract a subdirectory from an archive
- */
- QStringList MULTIMC_LOGIC_EXPORT extractSubDir(QuaZip *zip, const QString & subdir, const QString &target);
-}
diff --git a/libraries/logic/NullInstance.h b/libraries/logic/NullInstance.h
deleted file mode 100644
index fbb2d985..00000000
--- a/libraries/logic/NullInstance.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#pragma once
-#include "BaseInstance.h"
-
-class NullInstance: public BaseInstance
-{
-public:
- NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir)
- :BaseInstance(globalSettings, settings, rootDir)
- {
- setFlag(BaseInstance::VersionBrokenFlag);
- }
- virtual ~NullInstance() {};
- virtual bool setIntendedVersionId(QString) override
- {
- return false;
- }
- virtual void cleanupAfterRun() override
- {
- }
- virtual QString currentVersionId() const override
- {
- return "Null";
- };
- virtual QString intendedVersionId() const override
- {
- return "Null";
- };
- virtual void init() override
- {
- };
- virtual QString getStatusbarDescription() override
- {
- return tr("Unknown instance type");
- };
- virtual bool shouldUpdate() const override
- {
- return false;
- };
- virtual QSet< QString > traits() override
- {
- return {};
- };
- virtual QString instanceConfigFolder() const override
- {
- return instanceRoot();
- };
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr) override
- {
- return nullptr;
- }
- virtual std::shared_ptr< Task > createUpdateTask() override
- {
- return nullptr;
- }
- virtual std::shared_ptr<Task> createJarModdingTask() override
- {
- return nullptr;
- }
- virtual void setShouldUpdate(bool) override
- {
- };
- virtual std::shared_ptr< BaseVersionList > versionList() const override
- {
- return nullptr;
- };
- virtual QProcessEnvironment createEnvironment() override
- {
- return QProcessEnvironment();
- }
- virtual QMap<QString, QString> getVariables() const override
- {
- return QMap<QString, QString>();
- }
- virtual IPathMatcher::Ptr getLogFileMatcher() override
- {
- return nullptr;
- }
- virtual QString getLogFileRoot() override
- {
- return instanceRoot();
- }
- virtual QString typeName() const override
- {
- return "Null";
- }
- bool canExport() const override
- {
- return false;
- }
-};
diff --git a/libraries/logic/QObjectPtr.h b/libraries/logic/QObjectPtr.h
deleted file mode 100644
index b81b3234..00000000
--- a/libraries/logic/QObjectPtr.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#pragma once
-
-#include <memory>
-#include <QObject>
-
-namespace details
-{
-struct DeleteQObjectLater
-{
- void operator()(QObject *obj) const
- {
- obj->deleteLater();
- }
-};
-}
-/**
- * A unique pointer class with unique pointer semantics intended for derivates of QObject
- * Calls deleteLater() instead of destroying the contained object immediately
- */
-template<typename T> using unique_qobject_ptr = std::unique_ptr<T, details::DeleteQObjectLater>;
-
-/**
- * A shared pointer class with shared pointer semantics intended for derivates of QObject
- * Calls deleteLater() instead of destroying the contained object immediately
- */
-template <typename T>
-class shared_qobject_ptr
-{
-public:
- shared_qobject_ptr(){}
- shared_qobject_ptr(T * wrap)
- {
- reset(wrap);
- }
- shared_qobject_ptr(const shared_qobject_ptr<T>& other)
- {
- m_ptr = other.m_ptr;
- }
- template<typename Derived>
- shared_qobject_ptr(const shared_qobject_ptr<Derived> &other)
- {
- m_ptr = other.unwrap();
- }
-
-public:
- void reset(T * wrap)
- {
- using namespace std::placeholders;
- m_ptr.reset(wrap, std::bind(&QObject::deleteLater, _1));
- }
- void reset()
- {
- m_ptr.reset();
- }
- T * get() const
- {
- return m_ptr.get();
- }
- T * operator->() const
- {
- return m_ptr.get();
- }
- T & operator*() const
- {
- return *m_ptr.get();
- }
- operator bool() const
- {
- return m_ptr.get() != nullptr;
- }
- const std::shared_ptr <T> unwrap() const
- {
- return m_ptr;
- }
-
-private:
- std::shared_ptr <T> m_ptr;
-};
diff --git a/libraries/logic/RWStorage.h b/libraries/logic/RWStorage.h
deleted file mode 100644
index b1598ca4..00000000
--- a/libraries/logic/RWStorage.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-template <typename K, typename V>
-class RWStorage
-{
-public:
- void add(K key, V value)
- {
- QWriteLocker l(&lock);
- cache[key] = value;
- stale_entries.remove(key);
- }
- V get(K key)
- {
- QReadLocker l(&lock);
- if(cache.contains(key))
- {
- return cache[key];
- }
- else return V();
- }
- bool get(K key, V& value)
- {
- QReadLocker l(&lock);
- if(cache.contains(key))
- {
- value = cache[key];
- return true;
- }
- else return false;
- }
- bool has(K key)
- {
- QReadLocker l(&lock);
- return cache.contains(key);
- }
- bool stale(K key)
- {
- QReadLocker l(&lock);
- if(!cache.contains(key))
- return true;
- return stale_entries.contains(key);
- }
- void setStale(K key)
- {
- QReadLocker l(&lock);
- if(cache.contains(key))
- {
- stale_entries.insert(key);
- }
- }
- void clear()
- {
- QWriteLocker l(&lock);
- cache.clear();
- }
-private:
- QReadWriteLock lock;
- QMap<K, V> cache;
- QSet<K> stale_entries;
-}; \ No newline at end of file
diff --git a/libraries/logic/RecursiveFileSystemWatcher.cpp b/libraries/logic/RecursiveFileSystemWatcher.cpp
deleted file mode 100644
index 59c3f0f0..00000000
--- a/libraries/logic/RecursiveFileSystemWatcher.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "RecursiveFileSystemWatcher.h"
-
-#include <QRegularExpression>
-#include <QDebug>
-
-RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent)
- : QObject(parent), m_watcher(new QFileSystemWatcher(this))
-{
- connect(m_watcher, &QFileSystemWatcher::fileChanged, this,
- &RecursiveFileSystemWatcher::fileChange);
- connect(m_watcher, &QFileSystemWatcher::directoryChanged, this,
- &RecursiveFileSystemWatcher::directoryChange);
-}
-
-void RecursiveFileSystemWatcher::setRootDir(const QDir &root)
-{
- bool wasEnabled = m_isEnabled;
- disable();
- m_root = root;
- setFiles(scanRecursive(m_root));
- if (wasEnabled)
- {
- enable();
- }
-}
-void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles)
-{
- bool wasEnabled = m_isEnabled;
- disable();
- m_watchFiles = watchFiles;
- if (wasEnabled)
- {
- enable();
- }
-}
-
-void RecursiveFileSystemWatcher::enable()
-{
- if (m_isEnabled)
- {
- return;
- }
- Q_ASSERT(m_root != QDir::root());
- addFilesToWatcherRecursive(m_root);
- m_isEnabled = true;
-}
-void RecursiveFileSystemWatcher::disable()
-{
- if (!m_isEnabled)
- {
- return;
- }
- m_isEnabled = false;
- m_watcher->removePaths(m_watcher->files());
- m_watcher->removePaths(m_watcher->directories());
-}
-
-void RecursiveFileSystemWatcher::setFiles(const QStringList &files)
-{
- if (files != m_files)
- {
- m_files = files;
- emit filesChanged();
- }
-}
-
-void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir)
-{
- m_watcher->addPath(dir.absolutePath());
- for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
- {
- addFilesToWatcherRecursive(dir.absoluteFilePath(directory));
- }
- if (m_watchFiles)
- {
- for (const QFileInfo &info : dir.entryInfoList(QDir::Files))
- {
- m_watcher->addPath(info.absoluteFilePath());
- }
- }
-}
-QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &directory)
-{
- QStringList ret;
- if(!m_matcher)
- {
- return {};
- }
- for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden))
- {
- ret.append(scanRecursive(directory.absoluteFilePath(dir)));
- }
- for (const QString &file : directory.entryList(QDir::Files | QDir::Hidden))
- {
- auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
- if (m_matcher->matches(relPath))
- {
- ret.append(relPath);
- }
- }
- return ret;
-}
-
-void RecursiveFileSystemWatcher::fileChange(const QString &path)
-{
- emit fileChanged(path);
-}
-void RecursiveFileSystemWatcher::directoryChange(const QString &path)
-{
- setFiles(scanRecursive(m_root));
-}
diff --git a/libraries/logic/RecursiveFileSystemWatcher.h b/libraries/logic/RecursiveFileSystemWatcher.h
deleted file mode 100644
index 07bce0b9..00000000
--- a/libraries/logic/RecursiveFileSystemWatcher.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-#include <QFileSystemWatcher>
-#include <QDir>
-#include "pathmatcher/IPathMatcher.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT RecursiveFileSystemWatcher : public QObject
-{
- Q_OBJECT
-public:
- RecursiveFileSystemWatcher(QObject *parent);
-
- void setRootDir(const QDir &root);
- QDir rootDir() const
- {
- return m_root;
- }
-
- // WARNING: setting this to true may be bad for performance
- void setWatchFiles(const bool watchFiles);
- bool watchFiles() const
- {
- return m_watchFiles;
- }
-
- void setMatcher(IPathMatcher::Ptr matcher)
- {
- m_matcher = matcher;
- }
-
- QStringList files() const
- {
- return m_files;
- }
-
-signals:
- void filesChanged();
- void fileChanged(const QString &path);
-
-public slots:
- void enable();
- void disable();
-
-private:
- QDir m_root;
- bool m_watchFiles = false;
- bool m_isEnabled = false;
- IPathMatcher::Ptr m_matcher;
-
- QFileSystemWatcher *m_watcher;
-
- QStringList m_files;
- void setFiles(const QStringList &files);
-
- void addFilesToWatcherRecursive(const QDir &dir);
- QStringList scanRecursive(const QDir &dir);
-
-private slots:
- void fileChange(const QString &path);
- void directoryChange(const QString &path);
-};
diff --git a/libraries/logic/SeparatorPrefixTree.h b/libraries/logic/SeparatorPrefixTree.h
deleted file mode 100644
index fd149af0..00000000
--- a/libraries/logic/SeparatorPrefixTree.h
+++ /dev/null
@@ -1,298 +0,0 @@
-#pragma once
-#include <QString>
-#include <QMap>
-#include <QStringList>
-
-template <char Tseparator>
-class SeparatorPrefixTree
-{
-public:
- SeparatorPrefixTree(QStringList paths)
- {
- insert(paths);
- }
-
- SeparatorPrefixTree(bool contained = false)
- {
- m_contained = contained;
- }
-
- void insert(QStringList paths)
- {
- for(auto &path: paths)
- {
- insert(path);
- }
- }
-
- /// insert an exact path into the tree
- SeparatorPrefixTree & insert(QString path)
- {
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- children[path] = SeparatorPrefixTree(true);
- return children[path];
- }
- else
- {
- auto prefix = path.left(sepIndex);
- if(!children.contains(prefix))
- {
- children[prefix] = SeparatorPrefixTree(false);
- }
- return children[prefix].insert(path.mid(sepIndex + 1));
- }
- }
-
- /// is the path fully contained in the tree?
- bool contains(QString path) const
- {
- auto node = find(path);
- return node != nullptr;
- }
-
- /// does the tree cover a path? That means the prefix of the path is contained in the tree
- bool covers(QString path) const
- {
- // if we found some valid node, it's good enough. the tree covers the path
- if(m_contained)
- {
- return true;
- }
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return false;
- }
- return (*found).covers(QString());
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return false;
- }
- return (*found).covers(path.mid(sepIndex + 1));
- }
- }
-
- /// return the contained path that covers the path specified
- QString cover(QString path) const
- {
- // if we found some valid node, it's good enough. the tree covers the path
- if(m_contained)
- {
- return QString("");
- }
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return QString();
- }
- auto nested = (*found).cover(QString());
- if(nested.isNull())
- {
- return nested;
- }
- if(nested.isEmpty())
- return path;
- return path + Tseparator + nested;
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return QString();
- }
- auto nested = (*found).cover(path.mid(sepIndex + 1));
- if(nested.isNull())
- {
- return nested;
- }
- if(nested.isEmpty())
- return prefix;
- return prefix + Tseparator + nested;
- }
- }
-
- /// Does the path-specified node exist in the tree? It does not have to be contained.
- bool exists(QString path) const
- {
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return false;
- }
- return true;
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return false;
- }
- return (*found).exists(path.mid(sepIndex + 1));
- }
- }
-
- /// find a node in the tree by name
- const SeparatorPrefixTree * find(QString path) const
- {
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return nullptr;
- }
- return &(*found);
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return nullptr;
- }
- return (*found).find(path.mid(sepIndex + 1));
- }
- }
-
- /// is this a leaf node?
- bool leaf() const
- {
- return children.isEmpty();
- }
-
- /// is this node actually contained in the tree, or is it purely structural?
- bool contained() const
- {
- return m_contained;
- }
-
- /// Remove a path from the tree
- bool remove(QString path)
- {
- return removeInternal(path) != Failed;
- }
-
- /// Clear all children of this node tree node
- void clear()
- {
- children.clear();
- }
-
- QStringList toStringList() const
- {
- QStringList collected;
- // collecting these is more expensive.
- auto iter = children.begin();
- while(iter != children.end())
- {
- QStringList list = iter.value().toStringList();
- for(int i = 0; i < list.size(); i++)
- {
- list[i] = iter.key() + Tseparator + list[i];
- }
- collected.append(list);
- if((*iter).m_contained)
- {
- collected.append(iter.key());
- }
- iter++;
- }
- return collected;
- }
-private:
- enum Removal
- {
- Failed,
- Succeeded,
- HasChildren
- };
- Removal removeInternal(QString path = QString())
- {
- if(path.isEmpty())
- {
- if(!m_contained)
- {
- // remove all children - we are removing a prefix
- clear();
- return Succeeded;
- }
- m_contained = false;
- if(children.size())
- {
- return HasChildren;
- }
- return Succeeded;
- }
- Removal remStatus = Failed;
- QString childToRemove;
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- childToRemove = path;
- auto found = children.find(childToRemove);
- if(found == children.end())
- {
- return Failed;
- }
- remStatus = (*found).removeInternal();
- }
- else
- {
- childToRemove = path.left(sepIndex);
- auto found = children.find(childToRemove);
- if(found == children.end())
- {
- return Failed;
- }
- remStatus = (*found).removeInternal(path.mid(sepIndex + 1));
- }
- switch (remStatus)
- {
- case Failed:
- case HasChildren:
- {
- return remStatus;
- }
- case Succeeded:
- {
- children.remove(childToRemove);
- if(m_contained)
- {
- return HasChildren;
- }
- if(children.size())
- {
- return HasChildren;
- }
- return Succeeded;
- }
- }
- return Failed;
- }
-
-private:
- QMap<QString,SeparatorPrefixTree<Tseparator>> children;
- bool m_contained = false;
-};
diff --git a/libraries/logic/TypeMagic.h b/libraries/logic/TypeMagic.h
deleted file mode 100644
index fa9d12a9..00000000
--- a/libraries/logic/TypeMagic.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-namespace TypeMagic
-{
-/** "Cleans" the given type T by stripping references (&) and cv-qualifiers (const, volatile) from it
- * const int => int
- * QString & => QString
- * const unsigned long long & => unsigned long long
- *
- * Usage:
- * using Cleaned = Detail::CleanType<const int>;
- * static_assert(std::is_same<Cleaned, int>, "Cleaned == int");
- */
-// the order of remove_cv and remove_reference matters!
-template <typename T>
-using CleanType = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
-
-/// For functors (structs with operator()), including lambdas, which in **most** cases are functors
-/// "Calls" Function<Ret(*)(Arg)> or Function<Ret(C::*)(Arg)>
-template <typename T> struct Function : public Function<decltype(&T::operator())> {};
-/// For function pointers (&function), including static members (&Class::member)
-template <typename Ret, typename Arg> struct Function<Ret(*)(Arg)> : public Function<Ret(Arg)> {};
-/// Default specialization used by others.
-template <typename Ret, typename Arg> struct Function<Ret(Arg)>
-{
- using ReturnType = Ret;
- using Argument = Arg;
-};
-/// For member functions. Also used by the lambda overload if the lambda captures [this]
-template <class C, typename Ret, typename Arg> struct Function<Ret(C::*)(Arg)> : public Function<Ret(Arg)> {};
-template <class C, typename Ret, typename Arg> struct Function<Ret(C::*)(Arg) const> : public Function<Ret(Arg)> {};
-/// Overload for references
-template <typename F> struct Function<F&> : public Function<F> {};
-/// Overload for rvalues
-template <typename F> struct Function<F&&> : public Function<F> {};
-// for more info: https://functionalcpp.wordpress.com/2013/08/05/function-traits/
-}
diff --git a/libraries/logic/Version.cpp b/libraries/logic/Version.cpp
deleted file mode 100644
index 3c4727ad..00000000
--- a/libraries/logic/Version.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#include "Version.h"
-
-#include <QStringList>
-#include <QUrl>
-#include <QRegularExpression>
-#include <QRegularExpressionMatch>
-
-Version::Version(const QString &str) : m_string(str)
-{
- parse();
-}
-
-bool Version::operator<(const Version &other) const
-{
- const int size = qMax(m_sections.size(), other.m_sections.size());
- for (int i = 0; i < size; ++i)
- {
- const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
- const Section sec2 =
- (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
- if (sec1 != sec2)
- {
- return sec1 < sec2;
- }
- }
-
- return false;
-}
-bool Version::operator<=(const Version &other) const
-{
- return *this < other || *this == other;
-}
-bool Version::operator>(const Version &other) const
-{
- const int size = qMax(m_sections.size(), other.m_sections.size());
- for (int i = 0; i < size; ++i)
- {
- const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
- const Section sec2 =
- (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
- if (sec1 != sec2)
- {
- return sec1 > sec2;
- }
- }
-
- return false;
-}
-bool Version::operator>=(const Version &other) const
-{
- return *this > other || *this == other;
-}
-bool Version::operator==(const Version &other) const
-{
- const int size = qMax(m_sections.size(), other.m_sections.size());
- for (int i = 0; i < size; ++i)
- {
- const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
- const Section sec2 =
- (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
- if (sec1 != sec2)
- {
- return false;
- }
- }
-
- return true;
-}
-bool Version::operator!=(const Version &other) const
-{
- return !operator==(other);
-}
-
-void Version::parse()
-{
- m_sections.clear();
-
- QStringList parts = m_string.split('.');
-
- for (const auto part : parts)
- {
- m_sections.append(Section(part));
- }
-}
-
-bool versionIsInInterval(const QString &version, const QString &interval)
-{
- return versionIsInInterval(Version(version), interval);
-}
-bool versionIsInInterval(const Version &version, const QString &interval)
-{
- if (interval.isEmpty() || version.toString() == interval)
- {
- return true;
- }
-
- // Interval notation is used
- QRegularExpression exp(
- "(?<start>[\\[\\]\\(\\)])(?<bottom>.*?)(,(?<top>.*?))?(?<end>[\\[\\]\\(\\)]),?");
- QRegularExpressionMatch match = exp.match(interval);
- if (match.hasMatch())
- {
- const QChar start = match.captured("start").at(0);
- const QChar end = match.captured("end").at(0);
- const QString bottom = match.captured("bottom");
- const QString top = match.captured("top");
-
- // check if in range (bottom)
- if (!bottom.isEmpty())
- {
- const auto bottomVersion = Version(bottom);
- if ((start == '[') && !(version >= bottomVersion))
- {
- return false;
- }
- else if ((start == '(') && !(version > bottomVersion))
- {
- return false;
- }
- }
-
- // check if in range (top)
- if (!top.isEmpty())
- {
- const auto topVersion = Version(top);
- if ((end == ']') && !(version <= topVersion))
- {
- return false;
- }
- else if ((end == ')') && !(version < topVersion))
- {
- return false;
- }
- }
-
- return true;
- }
-
- return false;
-}
diff --git a/libraries/logic/Version.h b/libraries/logic/Version.h
deleted file mode 100644
index b5946ced..00000000
--- a/libraries/logic/Version.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QList>
-
-#include "multimc_logic_export.h"
-
-class QUrl;
-
-struct MULTIMC_LOGIC_EXPORT Version
-{
- 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;
-
- QString toString() const
- {
- return m_string;
- }
-
-private:
- QString m_string;
- struct Section
- {
- explicit Section(const QString &fullString)
- {
- m_fullString = fullString;
- int cutoff = m_fullString.size();
- for(int i = 0; i < m_fullString.size(); i++)
- {
- if(!m_fullString[i].isDigit())
- {
- cutoff = i;
- break;
- }
- }
- auto numPart = m_fullString.leftRef(cutoff);
- if(numPart.size())
- {
- numValid = true;
- m_numPart = numPart.toInt();
- }
- auto stringPart = m_fullString.midRef(cutoff);
- if(stringPart.size())
- {
- m_stringPart = stringPart.toString();
- }
- }
- explicit Section() {}
- bool numValid = false;
- int m_numPart = 0;
- QString m_stringPart;
- QString m_fullString;
-
- inline bool operator!=(const Section &other) const
- {
- if(numValid && other.numValid)
- {
- return m_numPart != other.m_numPart || m_stringPart != other.m_stringPart;
- }
- else
- {
- return m_fullString != other.m_fullString;
- }
- }
- inline bool operator<(const Section &other) const
- {
- if(numValid && other.numValid)
- {
- if(m_numPart < other.m_numPart)
- return true;
- if(m_numPart == other.m_numPart && m_stringPart < other.m_stringPart)
- return true;
- return false;
- }
- else
- {
- return m_fullString < other.m_fullString;
- }
- }
- inline bool operator>(const Section &other) const
- {
- if(numValid && other.numValid)
- {
- if(m_numPart > other.m_numPart)
- return true;
- if(m_numPart == other.m_numPart && m_stringPart > other.m_stringPart)
- return true;
- return false;
- }
- else
- {
- return m_fullString > other.m_fullString;
- }
- }
- };
- QList<Section> m_sections;
-
- void parse();
-};
-
-MULTIMC_LOGIC_EXPORT bool versionIsInInterval(const QString &version, const QString &interval);
-MULTIMC_LOGIC_EXPORT bool versionIsInInterval(const Version &version, const QString &interval);
-
diff --git a/libraries/logic/java/JavaChecker.cpp b/libraries/logic/java/JavaChecker.cpp
deleted file mode 100644
index 54d552a9..00000000
--- a/libraries/logic/java/JavaChecker.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-#include "JavaChecker.h"
-#include <FileSystem.h>
-#include <Commandline.h>
-#include <QFile>
-#include <QProcess>
-#include <QMap>
-#include <QCoreApplication>
-#include <QDebug>
-
-JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
-{
-}
-
-void JavaChecker::performCheck()
-{
- QString checkerJar = FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "JavaCheck.jar");
-
- QStringList args;
-
- process.reset(new QProcess());
- if(m_args.size())
- {
- auto extraArgs = Commandline::splitArgs(m_args);
- args.append(extraArgs);
- }
- if(m_minMem != 0)
- {
- args << QString("-Xms%1m").arg(m_minMem);
- }
- if(m_maxMem != 0)
- {
- args << QString("-Xmx%1m").arg(m_maxMem);
- }
- if(m_permGen != 64)
- {
- args << QString("-XX:PermSize=%1m").arg(m_permGen);
- }
-
- args.append({"-jar", checkerJar});
- process->setArguments(args);
- process->setProgram(m_path);
- process->setProcessChannelMode(QProcess::SeparateChannels);
- qDebug() << "Running java checker: " + m_path + args.join(" ");;
-
- connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
- connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
- connect(process.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(stdoutReady()));
- connect(process.get(), SIGNAL(readyReadStandardError()), this, SLOT(stderrReady()));
- connect(&killTimer, SIGNAL(timeout()), SLOT(timeout()));
- killTimer.setSingleShot(true);
- killTimer.start(15000);
- process->start();
-}
-
-void JavaChecker::stdoutReady()
-{
- QByteArray data = process->readAllStandardOutput();
- QString added = QString::fromLocal8Bit(data);
- added.remove('\r');
- m_stdout += added;
-}
-
-void JavaChecker::stderrReady()
-{
- QByteArray data = process->readAllStandardError();
- QString added = QString::fromLocal8Bit(data);
- added.remove('\r');
- m_stderr += added;
-}
-
-void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
-{
- killTimer.stop();
- QProcessPtr _process;
- _process.swap(process);
-
- JavaCheckResult result;
- {
- result.path = m_path;
- result.id = m_id;
- }
- result.errorLog = m_stderr;
- qDebug() << "STDOUT" << m_stdout;
- qWarning() << "STDERR" << m_stderr;
- qDebug() << "Java checker finished with status " << status << " exit code " << exitcode;
-
- if (status == QProcess::CrashExit || exitcode == 1)
- {
- qDebug() << "Java checker failed!";
- emit checkFinished(result);
- return;
- }
-
- bool success = true;
-
- QMap<QString, QString> results;
- QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
- for(QString line : lines)
- {
- line = line.trimmed();
-
- auto parts = line.split('=', QString::SkipEmptyParts);
- if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty())
- {
- success = false;
- }
- else
- {
- results.insert(parts[0], parts[1]);
- }
- }
-
- if(!results.contains("os.arch") || !results.contains("java.version") || !success)
- {
- qDebug() << "Java checker failed - couldn't extract required information.";
- emit checkFinished(result);
- return;
- }
-
- auto os_arch = results["os.arch"];
- auto java_version = results["java.version"];
- bool is_64 = os_arch == "x86_64" || os_arch == "amd64";
-
-
- result.valid = true;
- result.is_64bit = is_64;
- result.mojangPlatform = is_64 ? "64" : "32";
- result.realPlatform = os_arch;
- result.javaVersion = java_version;
- qDebug() << "Java checker succeeded.";
- emit checkFinished(result);
-}
-
-void JavaChecker::error(QProcess::ProcessError err)
-{
- if(err == QProcess::FailedToStart)
- {
- killTimer.stop();
- qDebug() << "Java checker has failed to start.";
- JavaCheckResult result;
- {
- result.path = m_path;
- result.id = m_id;
- }
-
- emit checkFinished(result);
- return;
- }
-}
-
-void JavaChecker::timeout()
-{
- // NO MERCY. NO ABUSE.
- if(process)
- {
- qDebug() << "Java checker has been killed by timeout.";
- process->kill();
- }
-}
diff --git a/libraries/logic/java/JavaChecker.h b/libraries/logic/java/JavaChecker.h
deleted file mode 100644
index 650e7ce3..00000000
--- a/libraries/logic/java/JavaChecker.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-#include <QProcess>
-#include <QTimer>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-#include "JavaVersion.h"
-
-class JavaChecker;
-
-struct MULTIMC_LOGIC_EXPORT JavaCheckResult
-{
- QString path;
- QString mojangPlatform;
- QString realPlatform;
- JavaVersion javaVersion;
- QString errorLog;
- bool valid = false;
- bool is_64bit = false;
- int id;
-};
-
-typedef std::shared_ptr<QProcess> QProcessPtr;
-typedef std::shared_ptr<JavaChecker> JavaCheckerPtr;
-class MULTIMC_LOGIC_EXPORT JavaChecker : public QObject
-{
- Q_OBJECT
-public:
- explicit JavaChecker(QObject *parent = 0);
- void performCheck();
-
- QString m_path;
- QString m_args;
- int m_id = 0;
- int m_minMem = 0;
- int m_maxMem = 0;
- int m_permGen = 64;
-
-signals:
- void checkFinished(JavaCheckResult result);
-private:
- QProcessPtr process;
- QTimer killTimer;
- QString m_stdout;
- QString m_stderr;
-public
-slots:
- void timeout();
- void finished(int exitcode, QProcess::ExitStatus);
- void error(QProcess::ProcessError);
- void stdoutReady();
- void stderrReady();
-};
diff --git a/libraries/logic/java/JavaCheckerJob.cpp b/libraries/logic/java/JavaCheckerJob.cpp
deleted file mode 100644
index 0b040e43..00000000
--- a/libraries/logic/java/JavaCheckerJob.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright 2013-2015 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 "JavaCheckerJob.h"
-
-#include <QDebug>
-
-void JavaCheckerJob::partFinished(JavaCheckResult result)
-{
- num_finished++;
- qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/"
- << javacheckers.size();
- emit progress(num_finished, javacheckers.size());
-
- javaresults.replace(result.id, result);
-
- if (num_finished == javacheckers.size())
- {
- emit finished(javaresults);
- }
-}
-
-void JavaCheckerJob::executeTask()
-{
- qDebug() << m_job_name.toLocal8Bit() << " started.";
- m_running = true;
- for (auto iter : javacheckers)
- {
- javaresults.append(JavaCheckResult());
- connect(iter.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult)));
- iter->performCheck();
- }
-}
diff --git a/libraries/logic/java/JavaCheckerJob.h b/libraries/logic/java/JavaCheckerJob.h
deleted file mode 100644
index aca0d02e..00000000
--- a/libraries/logic/java/JavaCheckerJob.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QtNetwork>
-#include "JavaChecker.h"
-#include "tasks/Task.h"
-
-class JavaCheckerJob;
-typedef std::shared_ptr<JavaCheckerJob> JavaCheckerJobPtr;
-
-class JavaCheckerJob : public Task
-{
- Q_OBJECT
-public:
- explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name) {};
-
- bool addJavaCheckerAction(JavaCheckerPtr base)
- {
- javacheckers.append(base);
- total_progress++;
- // if this is already running, the action needs to be started right away!
- if (isRunning())
- {
- setProgress(current_progress, total_progress);
- connect(base.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult)));
-
- base->performCheck();
- }
- return true;
- }
-
- JavaCheckerPtr operator[](int index)
- {
- return javacheckers[index];
- }
- ;
- JavaCheckerPtr first()
- {
- if (javacheckers.size())
- return javacheckers[0];
- return JavaCheckerPtr();
- }
- int size() const
- {
- return javacheckers.size();
- }
- virtual bool isRunning() const override
- {
- return m_running;
- }
-
-signals:
- void started();
- void finished(QList<JavaCheckResult>);
-
-private slots:
- void partFinished(JavaCheckResult result);
-
-protected:
- virtual void executeTask() override;
-
-private:
- QString m_job_name;
- QList<JavaCheckerPtr> javacheckers;
- QList<JavaCheckResult> javaresults;
- qint64 current_progress = 0;
- qint64 total_progress = 0;
- int num_finished = 0;
- bool m_running = false;
-};
diff --git a/libraries/logic/java/JavaInstall.cpp b/libraries/logic/java/JavaInstall.cpp
deleted file mode 100644
index bb262b6e..00000000
--- a/libraries/logic/java/JavaInstall.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "JavaInstall.h"
-#include <MMCStrings.h>
-
-bool JavaInstall::operator<(const JavaInstall &rhs)
-{
- auto archCompare = Strings::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive);
- if(archCompare != 0)
- return archCompare < 0;
- if(id < rhs.id)
- {
- return true;
- }
- if(id > rhs.id)
- {
- return false;
- }
- return Strings::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0;
-}
-
-bool JavaInstall::operator==(const JavaInstall &rhs)
-{
- return arch == rhs.arch && id == rhs.id && path == rhs.path;
-}
-
-bool JavaInstall::operator>(const JavaInstall &rhs)
-{
- return (!operator<(rhs)) && (!operator==(rhs));
-}
diff --git a/libraries/logic/java/JavaInstall.h b/libraries/logic/java/JavaInstall.h
deleted file mode 100644
index 882c7386..00000000
--- a/libraries/logic/java/JavaInstall.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "BaseVersion.h"
-#include "JavaVersion.h"
-
-struct JavaInstall : public BaseVersion
-{
- JavaInstall(){}
- JavaInstall(QString id, QString arch, QString path)
- : id(id), arch(arch), path(path)
- {
- }
- virtual QString descriptor()
- {
- return id.toString();
- }
-
- virtual QString name()
- {
- return id.toString();
- }
-
- virtual QString typeString() const
- {
- return arch;
- }
-
- bool operator<(const JavaInstall & rhs);
- bool operator==(const JavaInstall & rhs);
- bool operator>(const JavaInstall & rhs);
-
- JavaVersion id;
- QString arch;
- QString path;
- bool recommended = false;
-};
-
-typedef std::shared_ptr<JavaInstall> JavaInstallPtr;
diff --git a/libraries/logic/java/JavaInstallList.cpp b/libraries/logic/java/JavaInstallList.cpp
deleted file mode 100644
index c0729227..00000000
--- a/libraries/logic/java/JavaInstallList.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright 2013-2015 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 <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include <QDebug>
-
-#include "java/JavaInstallList.h"
-#include "java/JavaCheckerJob.h"
-#include "java/JavaUtils.h"
-#include "MMCStrings.h"
-#include "minecraft/VersionFilterData.h"
-
-JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *JavaInstallList::getLoadTask()
-{
- return new JavaListLoadTask(this);
-}
-
-const BaseVersionPtr JavaInstallList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-bool JavaInstallList::isLoaded()
-{
- return m_loaded;
-}
-
-int JavaInstallList::count() const
-{
- return m_vlist.count();
-}
-
-QVariant JavaInstallList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<JavaInstall>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
- case VersionIdRole:
- return version->descriptor();
- case VersionRole:
- return version->id.toString();
- case RecommendedRole:
- return version->recommended;
- case PathRole:
- return version->path;
- case ArchitectureRole:
- return version->arch;
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList JavaInstallList::providesRoles() const
-{
- return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole};
-}
-
-
-void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- sortVersions();
- if(m_vlist.size())
- {
- auto best = std::dynamic_pointer_cast<JavaInstall>(m_vlist[0]);
- best->recommended = true;
- }
- endResetModel();
-}
-
-bool sortJavas(BaseVersionPtr left, BaseVersionPtr right)
-{
- auto rleft = std::dynamic_pointer_cast<JavaInstall>(left);
- auto rright = std::dynamic_pointer_cast<JavaInstall>(right);
- return (*rleft) > (*rright);
-}
-
-void JavaInstallList::sortVersions()
-{
- beginResetModel();
- std::sort(m_vlist.begin(), m_vlist.end(), sortJavas);
- endResetModel();
-}
-
-JavaListLoadTask::JavaListLoadTask(JavaInstallList *vlist) : Task()
-{
- m_list = vlist;
- m_currentRecommended = NULL;
-}
-
-JavaListLoadTask::~JavaListLoadTask()
-{
-}
-
-void JavaListLoadTask::executeTask()
-{
- setStatus(tr("Detecting Java installations..."));
-
- JavaUtils ju;
- QList<QString> candidate_paths = ju.FindJavaPaths();
-
- m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
- connect(m_job.get(), SIGNAL(finished(QList<JavaCheckResult>)), this, SLOT(javaCheckerFinished(QList<JavaCheckResult>)));
- connect(m_job.get(), &Task::progress, this, &Task::setProgress);
-
- qDebug() << "Probing the following Java paths: ";
- int id = 0;
- for(QString candidate : candidate_paths)
- {
- qDebug() << " " << candidate;
-
- auto candidate_checker = new JavaChecker();
- candidate_checker->m_path = candidate;
- candidate_checker->m_id = id;
- m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker));
-
- id++;
- }
-
- m_job->start();
-}
-
-void JavaListLoadTask::javaCheckerFinished(QList<JavaCheckResult> results)
-{
- QList<JavaInstallPtr> candidates;
-
- qDebug() << "Found the following valid Java installations:";
- for(JavaCheckResult result : results)
- {
- if(result.valid)
- {
- JavaInstallPtr javaVersion(new JavaInstall());
-
- javaVersion->id = result.javaVersion;
- javaVersion->arch = result.mojangPlatform;
- javaVersion->path = result.path;
- candidates.append(javaVersion);
-
- qDebug() << " " << javaVersion->id.toString() << javaVersion->arch << javaVersion->path;
- }
- }
-
- QList<BaseVersionPtr> javas_bvp;
- for (auto java : candidates)
- {
- //qDebug() << java->id << java->arch << " at " << java->path;
- BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
-
- if (bp_java)
- {
- javas_bvp.append(java);
- }
- }
-
- m_list->updateListData(javas_bvp);
- emitSucceeded();
-}
diff --git a/libraries/logic/java/JavaInstallList.h b/libraries/logic/java/JavaInstallList.h
deleted file mode 100644
index cf0e5784..00000000
--- a/libraries/logic/java/JavaInstallList.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QAbstractListModel>
-
-#include "BaseVersionList.h"
-#include "tasks/Task.h"
-
-#include "JavaCheckerJob.h"
-#include "JavaInstall.h"
-
-#include "multimc_logic_export.h"
-
-class JavaListLoadTask;
-
-class MULTIMC_LOGIC_EXPORT JavaInstallList : public BaseVersionList
-{
- Q_OBJECT
-public:
- explicit JavaInstallList(QObject *parent = 0);
-
- virtual Task *getLoadTask() override;
- virtual bool isLoaded() override;
- virtual const BaseVersionPtr at(int i) const override;
- virtual int count() const override;
- virtual void sortVersions() override;
-
- virtual QVariant data(const QModelIndex &index, int role) const override;
- virtual RoleList providesRoles() const override;
-
-public slots:
- virtual void updateListData(QList<BaseVersionPtr> versions) override;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-};
-
-class JavaListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit JavaListLoadTask(JavaInstallList *vlist);
- ~JavaListLoadTask();
-
- virtual void executeTask();
-public slots:
- void javaCheckerFinished(QList<JavaCheckResult> results);
-
-protected:
- std::shared_ptr<JavaCheckerJob> m_job;
- JavaInstallList *m_list;
- JavaInstall *m_currentRecommended;
-};
diff --git a/libraries/logic/java/JavaUtils.cpp b/libraries/logic/java/JavaUtils.cpp
deleted file mode 100644
index 88996e9f..00000000
--- a/libraries/logic/java/JavaUtils.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright 2013-2015 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 <QStringList>
-#include <QString>
-#include <QDir>
-#include <QStringList>
-
-#include <settings/Setting.h>
-
-#include <QDebug>
-#include "java/JavaUtils.h"
-#include "java/JavaCheckerJob.h"
-#include "java/JavaInstallList.h"
-#include "FileSystem.h"
-
-JavaUtils::JavaUtils()
-{
-}
-
-JavaInstallPtr JavaUtils::MakeJavaPtr(QString path, QString id, QString arch)
-{
- JavaInstallPtr javaVersion(new JavaInstall());
-
- javaVersion->id = id;
- javaVersion->arch = arch;
- javaVersion->path = path;
-
- return javaVersion;
-}
-
-JavaInstallPtr JavaUtils::GetDefaultJava()
-{
- JavaInstallPtr javaVersion(new JavaInstall());
-
- javaVersion->id = "java";
- javaVersion->arch = "unknown";
- javaVersion->path = "java";
-
- return javaVersion;
-}
-
-#if defined(Q_OS_WIN32)
-QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName)
-{
- QList<JavaInstallPtr> javas;
-
- QString archType = "unknown";
- if (keyType == KEY_WOW64_64KEY)
- archType = "64";
- else if (keyType == KEY_WOW64_32KEY)
- archType = "32";
-
- HKEY jreKey;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName.toStdString().c_str(), 0,
- KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS)
- {
- // Read the current type version from the registry.
- // This will be used to find any key that contains the JavaHome value.
- char *value = new char[0];
- DWORD valueSz = 0;
- if (RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz) ==
- ERROR_MORE_DATA)
- {
- value = new char[valueSz];
- RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz);
- }
-
- QString recommended = value;
-
- TCHAR subKeyName[255];
- DWORD subKeyNameSize, numSubKeys, retCode;
-
- // Get the number of subkeys
- RegQueryInfoKey(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
-
- // Iterate until RegEnumKeyEx fails
- if (numSubKeys > 0)
- {
- for (int i = 0; i < numSubKeys; i++)
- {
- subKeyNameSize = 255;
- retCode = RegEnumKeyEx(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL,
- NULL);
- if (retCode == ERROR_SUCCESS)
- {
- // Now open the registry key for the version that we just got.
- QString newKeyName = keyName + "\\" + subKeyName;
-
- HKEY newKey;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0,
- KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS)
- {
- // Read the JavaHome value to find where Java is installed.
- value = new char[0];
- valueSz = 0;
- if (RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
- &valueSz) == ERROR_MORE_DATA)
- {
- value = new char[valueSz];
- RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
- &valueSz);
-
- // Now, we construct the version object and add it to the list.
- JavaInstallPtr javaVersion(new JavaInstall());
-
- javaVersion->id = subKeyName;
- javaVersion->arch = archType;
- javaVersion->path =
- QDir(FS::PathCombine(value, "bin")).absoluteFilePath("javaw.exe");
- javas.append(javaVersion);
- }
-
- RegCloseKey(newKey);
- }
- }
- }
- }
-
- RegCloseKey(jreKey);
- }
-
- return javas;
-}
-
-QList<QString> JavaUtils::FindJavaPaths()
-{
- QList<JavaInstallPtr> java_candidates;
-
- QList<JavaInstallPtr> JRE64s = this->FindJavaFromRegistryKey(
- KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
- QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey(
- KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
- QList<JavaInstallPtr> JRE32s = this->FindJavaFromRegistryKey(
- KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
- QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey(
- KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
-
- java_candidates.append(JRE64s);
- java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre7/bin/javaw.exe"));
- java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre6/bin/javaw.exe"));
- java_candidates.append(JDK64s);
- java_candidates.append(JRE32s);
- java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre7/bin/javaw.exe"));
- java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre6/bin/javaw.exe"));
- java_candidates.append(JDK32s);
- java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path));
-
- QList<QString> candidates;
- for(JavaInstallPtr java_candidate : java_candidates)
- {
- if(!candidates.contains(java_candidate->path))
- {
- candidates.append(java_candidate->path);
- }
- }
-
- return candidates;
-}
-
-#elif defined(Q_OS_MAC)
-QList<QString> JavaUtils::FindJavaPaths()
-{
- QList<QString> javas;
- javas.append(this->GetDefaultJava()->path);
- javas.append("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java");
- javas.append("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java");
- javas.append("/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java");
- QDir libraryJVMDir("/Library/Java/JavaVirtualMachines/");
- QStringList libraryJVMJavas = libraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QString &java, libraryJVMJavas) {
- javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
- javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/jre/bin/java");
- }
- QDir systemLibraryJVMDir("/System/Library/Java/JavaVirtualMachines/");
- QStringList systemLibraryJVMJavas = systemLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QString &java, systemLibraryJVMJavas) {
- javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
- javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
- }
- return javas;
-}
-
-#elif defined(Q_OS_LINUX)
-QList<QString> JavaUtils::FindJavaPaths()
-{
- qDebug() << "Linux Java detection incomplete - defaulting to \"java\"";
-
- QList<QString> javas;
- javas.append(this->GetDefaultJava()->path);
- javas.append("/opt/java/bin/java");
- javas.append("/usr/bin/java");
-
- return javas;
-}
-#else
-QList<QString> JavaUtils::FindJavaPaths()
-{
- qDebug() << "Unknown operating system build - defaulting to \"java\"";
-
- QList<QString> javas;
- javas.append(this->GetDefaultJava()->path);
-
- return javas;
-}
-#endif
diff --git a/libraries/logic/java/JavaUtils.h b/libraries/logic/java/JavaUtils.h
deleted file mode 100644
index 3fb88341..00000000
--- a/libraries/logic/java/JavaUtils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QStringList>
-
-#include "JavaCheckerJob.h"
-#include "JavaChecker.h"
-#include "JavaInstallList.h"
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#endif
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT JavaUtils : public QObject
-{
- Q_OBJECT
-public:
- JavaUtils();
-
- JavaInstallPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown");
- QList<QString> FindJavaPaths();
- JavaInstallPtr GetDefaultJava();
-
-#ifdef Q_OS_WIN
- QList<JavaInstallPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName);
-#endif
-};
diff --git a/libraries/logic/java/JavaVersion.cpp b/libraries/logic/java/JavaVersion.cpp
deleted file mode 100644
index 84fc48a4..00000000
--- a/libraries/logic/java/JavaVersion.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "JavaVersion.h"
-#include <MMCStrings.h>
-
-#include <QRegularExpression>
-#include <QString>
-
-JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
-{
- string = javaVersionString;
-
- auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int
- {
- auto str = match.captured(what);
- if(str.isEmpty())
- {
- return 0;
- }
- return str.toInt();
- };
-
- QRegularExpression pattern;
- if(javaVersionString.startsWith("1."))
- {
- pattern = QRegularExpression ("1[.](?<major>[0-9]+)([.](?<minor>[0-9]+))?(_(?<security>[0-9]+)?)?(-(?<prerelease>[a-zA-Z0-9]+))?");
- }
- else
- {
- pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
- }
-
- auto match = pattern.match(string);
- parseable = match.hasMatch();
- major = getCapturedInteger(match, "major");
- minor = getCapturedInteger(match, "minor");
- security = getCapturedInteger(match, "security");
- prerelease = match.captured("prerelease");
- return *this;
-}
-
-JavaVersion::JavaVersion(const QString &rhs)
-{
- operator=(rhs);
-}
-
-QString JavaVersion::toString()
-{
- return string;
-}
-
-bool JavaVersion::requiresPermGen()
-{
- if(parseable)
- {
- return major < 8;
- }
- return true;
-}
-
-bool JavaVersion::operator<(const JavaVersion &rhs)
-{
- if(parseable && rhs.parseable)
- {
- if(major < rhs.major)
- return true;
- if(major > rhs.major)
- return false;
- if(minor < rhs.minor)
- return true;
- if(minor > rhs.minor)
- return false;
- if(security < rhs.security)
- return true;
- if(security > rhs.security)
- return false;
-
- // everything else being equal, consider prerelease status
- bool thisPre = !prerelease.isEmpty();
- bool rhsPre = !rhs.prerelease.isEmpty();
- if(thisPre && !rhsPre)
- {
- // this is a prerelease and the other one isn't -> lesser
- return true;
- }
- else if(!thisPre && rhsPre)
- {
- // this isn't a prerelease and the other one is -> greater
- return false;
- }
- else if(thisPre && rhsPre)
- {
- // both are prereleases - use natural compare...
- return Strings::naturalCompare(prerelease, rhs.prerelease, Qt::CaseSensitive) < 0;
- }
- // neither is prerelease, so they are the same -> this cannot be less than rhs
- return false;
- }
- else return Strings::naturalCompare(string, rhs.string, Qt::CaseSensitive) < 0;
-}
-
-bool JavaVersion::operator==(const JavaVersion &rhs)
-{
- if(parseable && rhs.parseable)
- {
- return major == rhs.major && minor == rhs.minor && security == rhs.security && prerelease == rhs.prerelease;
- }
- return string == rhs.string;
-}
-
-bool JavaVersion::operator>(const JavaVersion &rhs)
-{
- return (!operator<(rhs)) && (!operator==(rhs));
-}
diff --git a/libraries/logic/java/JavaVersion.h b/libraries/logic/java/JavaVersion.h
deleted file mode 100644
index f9a733d3..00000000
--- a/libraries/logic/java/JavaVersion.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "multimc_logic_export.h"
-#include <QString>
-
-class MULTIMC_LOGIC_EXPORT JavaVersion
-{
- friend class JavaVersionTest;
-public:
- JavaVersion() {};
- JavaVersion(const QString & rhs);
-
- JavaVersion & operator=(const QString & rhs);
-
- bool operator<(const JavaVersion & rhs);
- bool operator==(const JavaVersion & rhs);
- bool operator>(const JavaVersion & rhs);
-
- bool requiresPermGen();
-
- QString toString();
-
-private:
- QString string;
- int major = 0;
- int minor = 0;
- int security = 0;
- bool parseable = false;
- QString prerelease;
-};
diff --git a/libraries/logic/launch/LaunchStep.cpp b/libraries/logic/launch/LaunchStep.cpp
deleted file mode 100644
index 3078043b..00000000
--- a/libraries/logic/launch/LaunchStep.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright 2013-2015 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 "LaunchStep.h"
-#include "LaunchTask.h"
-
-void LaunchStep::bind(LaunchTask *parent)
-{
- m_parent = parent;
- connect(this, &LaunchStep::readyForLaunch, parent, &LaunchTask::onReadyForLaunch);
- connect(this, &LaunchStep::logLine, parent, &LaunchTask::onLogLine);
- connect(this, &LaunchStep::logLines, parent, &LaunchTask::onLogLines);
- connect(this, &LaunchStep::finished, parent, &LaunchTask::onStepFinished);
- connect(this, &LaunchStep::progressReportingRequest, parent, &LaunchTask::onProgressReportingRequested);
-}
diff --git a/libraries/logic/launch/LaunchStep.h b/libraries/logic/launch/LaunchStep.h
deleted file mode 100644
index ea472c0d..00000000
--- a/libraries/logic/launch/LaunchStep.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "tasks/Task.h"
-#include "MessageLevel.h"
-
-#include <QStringList>
-
-class LaunchTask;
-class LaunchStep: public Task
-{
- Q_OBJECT
-public: /* methods */
- explicit LaunchStep(LaunchTask *parent):Task(nullptr), m_parent(parent)
- {
- bind(parent);
- };
- virtual ~LaunchStep() {};
-
-protected: /* methods */
- virtual void bind(LaunchTask *parent);
-
-signals:
- void logLines(QStringList lines, MessageLevel::Enum level);
- void logLine(QString line, MessageLevel::Enum level);
- void readyForLaunch();
- void progressReportingRequest();
-
-public slots:
- virtual void proceed() {};
-
-protected: /* data */
- LaunchTask *m_parent;
-}; \ No newline at end of file
diff --git a/libraries/logic/launch/LaunchTask.cpp b/libraries/logic/launch/LaunchTask.cpp
deleted file mode 100644
index 5b7ff182..00000000
--- a/libraries/logic/launch/LaunchTask.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
- *
- * 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 "launch/LaunchTask.h"
-#include "MessageLevel.h"
-#include "MMCStrings.h"
-#include "java/JavaChecker.h"
-#include "tasks/Task.h"
-#include <QDebug>
-#include <QDir>
-#include <QEventLoop>
-#include <QRegularExpression>
-#include <QCoreApplication>
-#include <QStandardPaths>
-#include <assert.h>
-
-void LaunchTask::init()
-{
- m_instance->setRunning(true);
-}
-
-std::shared_ptr<LaunchTask> LaunchTask::create(InstancePtr inst)
-{
- std::shared_ptr<LaunchTask> proc(new LaunchTask(inst));
- proc->init();
- return proc;
-}
-
-LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance)
-{
-}
-
-void LaunchTask::appendStep(std::shared_ptr<LaunchStep> step)
-{
- m_steps.append(step);
-}
-
-void LaunchTask::prependStep(std::shared_ptr<LaunchStep> step)
-{
- m_steps.prepend(step);
-}
-
-void LaunchTask::executeTask()
-{
- if(!m_steps.size())
- {
- state = LaunchTask::Finished;
- emitSucceeded();
- }
- state = LaunchTask::Running;
- onStepFinished();
-}
-
-void LaunchTask::onReadyForLaunch()
-{
- state = LaunchTask::Waiting;
- emit readyForLaunch();
-}
-
-void LaunchTask::onStepFinished()
-{
- // initial -> just start the first step
- if(currentStep == -1)
- {
- currentStep ++;
- m_steps[currentStep]->start();
- return;
- }
-
- auto step = m_steps[currentStep];
- if(step->successful())
- {
- // end?
- if(currentStep == m_steps.size() - 1)
- {
- emitSucceeded();
- }
- else
- {
- currentStep ++;
- step = m_steps[currentStep];
- step->start();
- }
- }
- else
- {
- emitFailed(step->failReason());
- }
-}
-
-void LaunchTask::onProgressReportingRequested()
-{
- state = LaunchTask::Waiting;
- emit requestProgress(m_steps[currentStep].get());
-}
-
-void LaunchTask::setCensorFilter(QMap<QString, QString> filter)
-{
- m_censorFilter = filter;
-}
-
-QString LaunchTask::censorPrivateInfo(QString in)
-{
- auto iter = m_censorFilter.begin();
- while (iter != m_censorFilter.end())
- {
- in.replace(iter.key(), iter.value());
- iter++;
- }
- return in;
-}
-
-void LaunchTask::proceed()
-{
- if(state != LaunchTask::Waiting)
- {
- return;
- }
- m_steps[currentStep]->proceed();
-}
-
-bool LaunchTask::abort()
-{
- switch(state)
- {
- case LaunchTask::Aborted:
- case LaunchTask::Failed:
- case LaunchTask::Finished:
- return true;
- case LaunchTask::NotStarted:
- {
- state = LaunchTask::Aborted;
- emitFailed("Aborted");
- return true;
- }
- case LaunchTask::Running:
- case LaunchTask::Waiting:
- {
- auto step = m_steps[currentStep];
- if(!step->canAbort())
- {
- return false;
- }
- if(step->abort())
- {
- state = LaunchTask::Aborted;
- return true;
- }
- }
- default:
- break;
- }
- return false;
-}
-
-void LaunchTask::onLogLines(const QStringList &lines, MessageLevel::Enum defaultLevel)
-{
- for (auto & line: lines)
- {
- onLogLine(line, defaultLevel);
- }
-}
-
-void LaunchTask::onLogLine(QString line, MessageLevel::Enum level)
-{
- // if the launcher part set a log level, use it
- auto innerLevel = MessageLevel::fromLine(line);
- if(innerLevel != MessageLevel::Unknown)
- {
- level = innerLevel;
- }
-
- // If the level is still undetermined, guess level
- if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown)
- {
- level = m_instance->guessLevel(line, level);
- }
-
- // censor private user info
- line = censorPrivateInfo(line);
-
- emit log(line, level);
-}
-
-void LaunchTask::emitSucceeded()
-{
- m_instance->cleanupAfterRun();
- m_instance->setRunning(false);
- Task::emitSucceeded();
-}
-
-void LaunchTask::emitFailed(QString reason)
-{
- m_instance->cleanupAfterRun();
- m_instance->setRunning(false);
- Task::emitFailed(reason);
-}
-
-QString LaunchTask::substituteVariables(const QString &cmd) const
-{
- QString out = cmd;
- auto variables = m_instance->getVariables();
- for (auto it = variables.begin(); it != variables.end(); ++it)
- {
- out.replace("$" + it.key(), it.value());
- }
- auto env = QProcessEnvironment::systemEnvironment();
- for (auto var : env.keys())
- {
- out.replace("$" + var, env.value(var));
- }
- return out;
-}
-
diff --git a/libraries/logic/launch/LaunchTask.h b/libraries/logic/launch/LaunchTask.h
deleted file mode 100644
index 447445ca..00000000
--- a/libraries/logic/launch/LaunchTask.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <QProcess>
-#include "BaseInstance.h"
-#include "MessageLevel.h"
-#include "LoggedProcess.h"
-#include "LaunchStep.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT LaunchTask: public Task
-{
- Q_OBJECT
-protected:
- explicit LaunchTask(InstancePtr instance);
- void init();
-
-public:
- enum State
- {
- NotStarted,
- Running,
- Waiting,
- Failed,
- Aborted,
- Finished
- };
-
-public: /* methods */
- static std::shared_ptr<LaunchTask> create(InstancePtr inst);
- virtual ~LaunchTask() {};
-
- void appendStep(std::shared_ptr<LaunchStep> step);
- void prependStep(std::shared_ptr<LaunchStep> step);
- void setCensorFilter(QMap<QString, QString> filter);
-
- InstancePtr instance()
- {
- return m_instance;
- }
-
- void setPid(qint64 pid)
- {
- m_pid = pid;
- }
-
- qint64 pid()
- {
- return m_pid;
- }
-
- /**
- * @brief prepare the process for launch (for multi-stage launch)
- */
- virtual void executeTask() override;
-
- /**
- * @brief launch the armed instance
- */
- void proceed();
-
- /**
- * @brief abort launch
- */
- virtual bool abort() override;
-
-public:
- QString substituteVariables(const QString &cmd) const;
- QString censorPrivateInfo(QString in);
-
-protected: /* methods */
- virtual void emitFailed(QString reason) override;
- virtual void emitSucceeded() override;
-
-signals:
- /**
- * @brief emitted when the launch preparations are done
- */
- void readyForLaunch();
-
- void requestProgress(Task *task);
-
- void requestLogging();
-
- /**
- * @brief emitted when we want to log something
- * @param text the text to log
- * @param level the level to log at
- */
- void log(QString text, MessageLevel::Enum level = MessageLevel::MultiMC);
-
-public slots:
- void onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel = MessageLevel::MultiMC);
- void onLogLine(QString line, MessageLevel::Enum defaultLevel = MessageLevel::MultiMC);
- void onReadyForLaunch();
- void onStepFinished();
- void onProgressReportingRequested();
-
-protected: /* data */
- InstancePtr m_instance;
- QList <std::shared_ptr<LaunchStep>> m_steps;
- QMap<QString, QString> m_censorFilter;
- int currentStep = -1;
- State state = NotStarted;
- qint64 m_pid = -1;
-};
diff --git a/libraries/logic/launch/LoggedProcess.cpp b/libraries/logic/launch/LoggedProcess.cpp
deleted file mode 100644
index 88ca40aa..00000000
--- a/libraries/logic/launch/LoggedProcess.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-#include "LoggedProcess.h"
-#include "MessageLevel.h"
-#include <QDebug>
-
-LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent)
-{
- // QProcess has a strange interface... let's map a lot of those into a few.
- connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut);
- connect(this, &QProcess::readyReadStandardError, this, &LoggedProcess::on_stdErr);
- connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(on_exit(int,QProcess::ExitStatus)));
- connect(this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(on_error(QProcess::ProcessError)));
- connect(this, &QProcess::stateChanged, this, &LoggedProcess::on_stateChange);
-}
-
-QStringList reprocess(const QByteArray & data, QString & leftover)
-{
- QString str = leftover + QString::fromLocal8Bit(data);
-
- str.remove('\r');
- QStringList lines = str.split("\n");
- leftover = lines.takeLast();
- return lines;
-}
-
-void LoggedProcess::on_stdErr()
-{
- auto lines = reprocess(readAllStandardError(), m_err_leftover);
- emit log(lines, MessageLevel::StdErr);
-}
-
-void LoggedProcess::on_stdOut()
-{
- auto lines = reprocess(readAllStandardOutput(), m_out_leftover);
- emit log(lines, MessageLevel::StdOut);
-}
-
-void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
-{
- // save the exit code
- m_exit_code = exit_code;
-
- // Flush console window
- if (!m_err_leftover.isEmpty())
- {
- emit log({m_err_leftover}, MessageLevel::StdErr);
- m_err_leftover.clear();
- }
- if (!m_out_leftover.isEmpty())
- {
- emit log({m_err_leftover}, MessageLevel::StdOut);
- m_out_leftover.clear();
- }
-
- // based on state, send signals
- if (!m_is_aborting)
- {
- if (status == QProcess::NormalExit)
- {
- //: Message displayed on instance exit
- emit log({tr("Process exited with code %1.").arg(exit_code)}, MessageLevel::MultiMC);
- changeState(LoggedProcess::Finished);
- }
- else
- {
- //: Message displayed on instance crashed
- if(exit_code == -1)
- emit log({tr("Process crashed.")}, MessageLevel::MultiMC);
- else
- emit log({tr("Process crashed with exitcode %1.").arg(exit_code)}, MessageLevel::MultiMC);
- changeState(LoggedProcess::Crashed);
- }
- }
- else
- {
- //: Message displayed after the instance exits due to kill request
- emit log({tr("Process was killed by user.")}, MessageLevel::Error);
- changeState(LoggedProcess::Aborted);
- }
-}
-
-void LoggedProcess::on_error(QProcess::ProcessError error)
-{
- switch(error)
- {
- case QProcess::FailedToStart:
- {
- emit log({tr("The process failed to start.")}, MessageLevel::Fatal);
- changeState(LoggedProcess::FailedToStart);
- break;
- }
- // we'll just ignore those... never needed them
- case QProcess::Crashed:
- case QProcess::ReadError:
- case QProcess::Timedout:
- case QProcess::UnknownError:
- case QProcess::WriteError:
- break;
- }
-}
-
-void LoggedProcess::kill()
-{
- m_is_aborting = true;
- QProcess::kill();
-}
-
-int LoggedProcess::exitCode() const
-{
- return m_exit_code;
-}
-
-void LoggedProcess::changeState(LoggedProcess::State state)
-{
- if(state == m_state)
- return;
- m_state = state;
- emit stateChanged(m_state);
-}
-
-LoggedProcess::State LoggedProcess::state() const
-{
- return m_state;
-}
-
-void LoggedProcess::on_stateChange(QProcess::ProcessState state)
-{
- switch(state)
- {
- case QProcess::NotRunning:
- break; // let's not - there are too many that handle this already.
- case QProcess::Starting:
- {
- if(m_state != LoggedProcess::NotRunning)
- {
- qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Starting;
- }
- changeState(LoggedProcess::Starting);
- return;
- }
- case QProcess::Running:
- {
- if(m_state != LoggedProcess::Starting)
- {
- qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Running;
- }
- changeState(LoggedProcess::Running);
- return;
- }
- }
-}
-
-#if defined Q_OS_WIN32
-#include <windows.h>
-#endif
-
-qint64 LoggedProcess::processId() const
-{
-#ifdef Q_OS_WIN
- return pid() ? pid()->dwProcessId : 0;
-#else
- return pid();
-#endif
-}
diff --git a/libraries/logic/launch/LoggedProcess.h b/libraries/logic/launch/LoggedProcess.h
deleted file mode 100644
index baa53d79..00000000
--- a/libraries/logic/launch/LoggedProcess.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QProcess>
-#include "MessageLevel.h"
-
-/*
- * This is a basic process.
- * It has line-based logging support and hides some of the nasty bits.
- */
-class LoggedProcess : public QProcess
-{
-Q_OBJECT
-public:
- enum State
- {
- NotRunning,
- Starting,
- FailedToStart,
- Running,
- Finished,
- Crashed,
- Aborted
- };
-
-public:
- explicit LoggedProcess(QObject* parent = 0);
- virtual ~LoggedProcess() {};
-
- State state() const;
- int exitCode() const;
- qint64 processId() const;
-
-signals:
- void log(QStringList lines, MessageLevel::Enum level);
- void stateChanged(LoggedProcess::State state);
-
-public slots:
- /**
- * @brief kill the process - equivalent to kill -9
- */
- void kill();
-
-
-private slots:
- void on_stdErr();
- void on_stdOut();
- void on_exit(int exit_code, QProcess::ExitStatus status);
- void on_error(QProcess::ProcessError error);
- void on_stateChange(QProcess::ProcessState);
-
-private:
- void changeState(LoggedProcess::State state);
-
-private:
- QString m_err_leftover;
- QString m_out_leftover;
- bool m_killed = false;
- State m_state = NotRunning;
- int m_exit_code = 0;
- bool m_is_aborting = false;
-};
diff --git a/libraries/logic/launch/MessageLevel.cpp b/libraries/logic/launch/MessageLevel.cpp
deleted file mode 100644
index a5191290..00000000
--- a/libraries/logic/launch/MessageLevel.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "MessageLevel.h"
-
-MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
-{
- if (levelName == "MultiMC")
- return MessageLevel::MultiMC;
- else if (levelName == "Debug")
- return MessageLevel::Debug;
- else if (levelName == "Info")
- return MessageLevel::Info;
- else if (levelName == "Message")
- return MessageLevel::Message;
- else if (levelName == "Warning")
- return MessageLevel::Warning;
- else if (levelName == "Error")
- return MessageLevel::Error;
- else if (levelName == "Fatal")
- return MessageLevel::Fatal;
- // Skip PrePost, it's not exposed to !![]!
- // Also skip StdErr and StdOut
- else
- return MessageLevel::Unknown;
-}
-
-MessageLevel::Enum MessageLevel::fromLine(QString &line)
-{
- // Level prefix
- int endmark = line.indexOf("]!");
- if (line.startsWith("!![") && endmark != -1)
- {
- auto level = MessageLevel::getLevel(line.left(endmark).mid(3));
- line = line.mid(endmark + 2);
- return level;
- }
- return MessageLevel::Unknown;
-}
diff --git a/libraries/logic/launch/MessageLevel.h b/libraries/logic/launch/MessageLevel.h
deleted file mode 100644
index 0128148d..00000000
--- a/libraries/logic/launch/MessageLevel.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include <QString>
-
-/**
- * @brief the MessageLevel Enum
- * defines what level a log message is
- */
-namespace MessageLevel
-{
-enum Enum
-{
- Unknown, /**< No idea what this is or where it came from */
- StdOut, /**< Undetermined stderr messages */
- StdErr, /**< Undetermined stdout messages */
- MultiMC, /**< MultiMC Messages */
- Debug, /**< Debug Messages */
- Info, /**< Info Messages */
- Message, /**< Standard Messages */
- Warning, /**< Warnings */
- Error, /**< Errors */
- Fatal, /**< Fatal Errors */
-};
-MessageLevel::Enum getLevel(const QString &levelName);
-
-/* Get message level from a line. Line is modified if it was successful. */
-MessageLevel::Enum fromLine(QString &line);
-}
diff --git a/libraries/logic/launch/steps/CheckJava.cpp b/libraries/logic/launch/steps/CheckJava.cpp
deleted file mode 100644
index a4eaa307..00000000
--- a/libraries/logic/launch/steps/CheckJava.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright 2013-2015 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 "CheckJava.h"
-#include <launch/LaunchTask.h>
-#include <FileSystem.h>
-#include <QStandardPaths>
-#include <QFileInfo>
-
-void CheckJava::executeTask()
-{
- auto instance = m_parent->instance();
- auto settings = instance->settings();
- m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString());
- bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool();
-
- auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
- if (realJavaPath.isEmpty())
- {
- if (perInstance)
- {
- emit logLine(
- tr("The java binary \"%1\" couldn't be found. Please fix the java path "
- "override in the instance's settings or disable it.").arg(m_javaPath),
- MessageLevel::Warning);
- }
- else
- {
- emit logLine(tr("The java binary \"%1\" couldn't be found. Please set up java in "
- "the settings.").arg(m_javaPath),
- MessageLevel::Warning);
- }
- emitFailed(tr("Java path is not valid."));
- return;
- }
- else
- {
- emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::MultiMC);
- }
-
- QFileInfo javaInfo(realJavaPath);
- qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
- auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
- m_javaUnixTime = javaUnixTime;
- // if they are not the same, check!
- if (javaUnixTime != storedUnixTime)
- {
- m_JavaChecker = std::make_shared<JavaChecker>();
- QString errorLog;
- QString version;
- emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
- connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this,
- &CheckJava::checkJavaFinished);
- m_JavaChecker->m_path = realJavaPath;
- m_JavaChecker->performCheck();
- return;
- }
- emitSucceeded();
-}
-
-void CheckJava::checkJavaFinished(JavaCheckResult result)
-{
- if (!result.valid)
- {
- // Error message displayed if java can't start
- emit logLine(tr("Could not start java:"), MessageLevel::Error);
- emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
- emit logLine("\nCheck your MultiMC Java settings.", MessageLevel::MultiMC);
- emitFailed(tr("Could not start java!"));
- }
- else
- {
- auto instance = m_parent->instance();
- emit logLine(tr("Java version is %1!\n").arg(result.javaVersion.toString()),
- MessageLevel::MultiMC);
- instance->settings()->set("JavaVersion", result.javaVersion.toString());
- instance->settings()->set("JavaTimestamp", m_javaUnixTime);
- emitSucceeded();
- }
-}
diff --git a/libraries/logic/launch/steps/CheckJava.h b/libraries/logic/launch/steps/CheckJava.h
deleted file mode 100644
index b63dd4f4..00000000
--- a/libraries/logic/launch/steps/CheckJava.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
-#include <java/JavaChecker.h>
-
-class CheckJava: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit CheckJava(LaunchTask *parent) :LaunchStep(parent){};
- virtual ~CheckJava() {};
-
- virtual void executeTask();
- virtual bool canAbort() const
- {
- return false;
- }
-private slots:
- void checkJavaFinished(JavaCheckResult result);
-
-private:
- QString m_javaPath;
- qlonglong m_javaUnixTime;
- JavaCheckerPtr m_JavaChecker;
-};
diff --git a/libraries/logic/launch/steps/LaunchMinecraft.cpp b/libraries/logic/launch/steps/LaunchMinecraft.cpp
deleted file mode 100644
index 77a89f17..00000000
--- a/libraries/logic/launch/steps/LaunchMinecraft.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/* Copyright 2013-2015 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 "LaunchMinecraft.h"
-#include <launch/LaunchTask.h>
-#include <minecraft/MinecraftInstance.h>
-#include <FileSystem.h>
-#include <QStandardPaths>
-
-LaunchMinecraft::LaunchMinecraft(LaunchTask *parent) : LaunchStep(parent)
-{
- connect(&m_process, &LoggedProcess::log, this, &LaunchMinecraft::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &LaunchMinecraft::on_state);
-}
-
-void LaunchMinecraft::executeTask()
-{
- auto instance = m_parent->instance();
- std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
-
- m_launchScript = minecraftInstance->createLaunchScript(m_session);
-
- QStringList args = minecraftInstance->javaArguments();
-
- // HACK: this is a workaround for MCL-3732 - 'server-resource-packs' is created.
- if(!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->minecraftRoot(), "server-resource-packs")))
- {
- emit logLine(tr("Couldn't create the 'server-resource-packs' folder"), MessageLevel::Error);
- }
-
- QString allArgs = args.join(", ");
- emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
-
- auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
-
- m_process.setProcessEnvironment(instance->createEnvironment());
-
- QString wrapperCommand = instance->getWrapperCommand();
- if(!wrapperCommand.isEmpty())
- {
- auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
- if (realWrapperCommand.isEmpty())
- {
- QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand);
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- return;
- }
- emit logLine("Wrapper command is:\n" + wrapperCommand + "\n\n", MessageLevel::MultiMC);
- args.prepend(javaPath);
- m_process.start(wrapperCommand, args);
- }
- else
- {
- m_process.start(javaPath, args);
- }
-}
-
-void LaunchMinecraft::on_state(LoggedProcess::State state)
-{
- switch(state)
- {
- case LoggedProcess::FailedToStart:
- {
- //: Error message displayed if instace can't start
- QString reason = tr("Could not launch minecraft!");
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- return;
- }
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
-
- {
- m_parent->setPid(-1);
- emitFailed("Game crashed.");
- return;
- }
- case LoggedProcess::Finished:
- {
- m_parent->setPid(-1);
- // if the exit code wasn't 0, report this as a crash
- auto exitCode = m_process.exitCode();
- if(exitCode != 0)
- {
- emitFailed("Game crashed.");
- return;
- }
- //FIXME: make this work again
- // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode));
- // run post-exit
- emitSucceeded();
- break;
- }
- case LoggedProcess::Running:
- emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
- m_parent->setPid(m_process.processId());
- m_parent->instance()->setLastLaunch();
- // send the launch script to the launcher part
- m_process.write(m_launchScript.toUtf8());
-
- mayProceed = true;
- emit readyForLaunch();
- break;
- default:
- break;
- }
-}
-
-void LaunchMinecraft::setWorkingDirectory(const QString &wd)
-{
- m_process.setWorkingDirectory(wd);
-}
-
-void LaunchMinecraft::proceed()
-{
- if(mayProceed)
- {
- QString launchString("launch\n");
- m_process.write(launchString.toUtf8());
- mayProceed = false;
- }
-}
-
-bool LaunchMinecraft::abort()
-{
- if(mayProceed)
- {
- mayProceed = false;
- QString launchString("abort\n");
- m_process.write(launchString.toUtf8());
- }
- else
- {
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- }
- return true;
-}
diff --git a/libraries/logic/launch/steps/LaunchMinecraft.h b/libraries/logic/launch/steps/LaunchMinecraft.h
deleted file mode 100644
index 6b9f7919..00000000
--- a/libraries/logic/launch/steps/LaunchMinecraft.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
-#include <minecraft/auth/AuthSession.h>
-
-class LaunchMinecraft: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit LaunchMinecraft(LaunchTask *parent);
- virtual void executeTask();
- virtual bool abort();
- virtual void proceed();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
- void setAuthSession(AuthSessionPtr session)
- {
- m_session = session;
- }
-private slots:
- void on_state(LoggedProcess::State state);
-
-private:
- LoggedProcess m_process;
- QString m_command;
- QString m_launchScript;
- AuthSessionPtr m_session;
- bool mayProceed = false;
-};
diff --git a/libraries/logic/launch/steps/ModMinecraftJar.cpp b/libraries/logic/launch/steps/ModMinecraftJar.cpp
deleted file mode 100644
index fce2d70a..00000000
--- a/libraries/logic/launch/steps/ModMinecraftJar.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2013-2015 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 "ModMinecraftJar.h"
-#include <launch/LaunchTask.h>
-#include <QStandardPaths>
-
-void ModMinecraftJar::executeTask()
-{
- m_jarModTask = m_parent->instance()->createJarModdingTask();
- if(m_jarModTask)
- {
- connect(m_jarModTask.get(), SIGNAL(finished()), this, SLOT(jarModdingFinished()));
- m_jarModTask->start();
- return;
- }
- emitSucceeded();
-}
-
-void ModMinecraftJar::jarModdingFinished()
-{
- if(m_jarModTask->successful())
- {
- emitSucceeded();
- }
- else
- {
- QString reason = tr("jar modding failed because: %1.\n\n").arg(m_jarModTask->failReason());
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- }
-}
diff --git a/libraries/logic/launch/steps/ModMinecraftJar.h b/libraries/logic/launch/steps/ModMinecraftJar.h
deleted file mode 100644
index b35dfafa..00000000
--- a/libraries/logic/launch/steps/ModMinecraftJar.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <memory>
-
-// FIXME: temporary wrapper for existing task.
-class ModMinecraftJar: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit ModMinecraftJar(LaunchTask *parent) : LaunchStep(parent) {};
- virtual ~ModMinecraftJar(){};
-
- virtual void executeTask();
- virtual bool canAbort() const
- {
- return false;
- }
-private slots:
- void jarModdingFinished();
-
-private:
- std::shared_ptr<Task> m_jarModTask;
-};
diff --git a/libraries/logic/launch/steps/PostLaunchCommand.cpp b/libraries/logic/launch/steps/PostLaunchCommand.cpp
deleted file mode 100644
index 29a45f1b..00000000
--- a/libraries/logic/launch/steps/PostLaunchCommand.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright 2013-2015 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 "PostLaunchCommand.h"
-#include <launch/LaunchTask.h>
-
-PostLaunchCommand::PostLaunchCommand(LaunchTask *parent) : LaunchStep(parent)
-{
- auto instance = m_parent->instance();
- m_command = instance->getPostExitCommand();
- m_process.setProcessEnvironment(instance->createEnvironment());
- connect(&m_process, &LoggedProcess::log, this, &PostLaunchCommand::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &PostLaunchCommand::on_state);
-}
-
-void PostLaunchCommand::executeTask()
-{
- QString postlaunch_cmd = m_parent->substituteVariables(m_command);
- emit logLine(tr("Running Post-Launch command: %1").arg(postlaunch_cmd), MessageLevel::MultiMC);
- m_process.start(postlaunch_cmd);
-}
-
-void PostLaunchCommand::on_state(LoggedProcess::State state)
-{
- auto getError = [&]()
- {
- return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
- };
- switch(state)
- {
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
- case LoggedProcess::FailedToStart:
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- return;
- }
- case LoggedProcess::Finished:
- {
- if(m_process.exitCode() != 0)
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- }
- else
- {
- emit logLine(tr("Post-Launch command ran successfully.\n\n"), MessageLevel::MultiMC);
- emitSucceeded();
- }
- }
- default:
- break;
- }
-}
-
-void PostLaunchCommand::setWorkingDirectory(const QString &wd)
-{
- m_process.setWorkingDirectory(wd);
-}
-
-bool PostLaunchCommand::abort()
-{
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- return true;
-}
diff --git a/libraries/logic/launch/steps/PostLaunchCommand.h b/libraries/logic/launch/steps/PostLaunchCommand.h
deleted file mode 100644
index 4d5b0a52..00000000
--- a/libraries/logic/launch/steps/PostLaunchCommand.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
-
-class PostLaunchCommand: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit PostLaunchCommand(LaunchTask *parent);
- virtual void executeTask();
- virtual bool abort();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
-private slots:
- void on_state(LoggedProcess::State state);
-
-private:
- LoggedProcess m_process;
- QString m_command;
-};
diff --git a/libraries/logic/launch/steps/PreLaunchCommand.cpp b/libraries/logic/launch/steps/PreLaunchCommand.cpp
deleted file mode 100644
index 47197a82..00000000
--- a/libraries/logic/launch/steps/PreLaunchCommand.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright 2013-2015 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 "PreLaunchCommand.h"
-#include <launch/LaunchTask.h>
-
-PreLaunchCommand::PreLaunchCommand(LaunchTask *parent) : LaunchStep(parent)
-{
- auto instance = m_parent->instance();
- m_command = instance->getPreLaunchCommand();
- m_process.setProcessEnvironment(instance->createEnvironment());
- connect(&m_process, &LoggedProcess::log, this, &PreLaunchCommand::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &PreLaunchCommand::on_state);
-}
-
-void PreLaunchCommand::executeTask()
-{
- //FIXME: where to put this?
- QString prelaunch_cmd = m_parent->substituteVariables(m_command);
- emit logLine(tr("Running Pre-Launch command: %1").arg(prelaunch_cmd), MessageLevel::MultiMC);
- m_process.start(prelaunch_cmd);
-}
-
-void PreLaunchCommand::on_state(LoggedProcess::State state)
-{
- auto getError = [&]()
- {
- return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
- };
- switch(state)
- {
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
- case LoggedProcess::FailedToStart:
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- return;
- }
- case LoggedProcess::Finished:
- {
- if(m_process.exitCode() != 0)
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- }
- else
- {
- emit logLine(tr("Pre-Launch command ran successfully.\n\n"), MessageLevel::MultiMC);
- emitSucceeded();
- }
- }
- default:
- break;
- }
-}
-
-void PreLaunchCommand::setWorkingDirectory(const QString &wd)
-{
- m_process.setWorkingDirectory(wd);
-}
-
-bool PreLaunchCommand::abort()
-{
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- return true;
-}
diff --git a/libraries/logic/launch/steps/PreLaunchCommand.h b/libraries/logic/launch/steps/PreLaunchCommand.h
deleted file mode 100644
index 077bdfca..00000000
--- a/libraries/logic/launch/steps/PreLaunchCommand.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
-
-class PreLaunchCommand: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit PreLaunchCommand(LaunchTask *parent);
- virtual void executeTask();
- virtual bool abort();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
-private slots:
- void on_state(LoggedProcess::State state);
-
-private:
- LoggedProcess m_process;
- QString m_command;
-};
diff --git a/libraries/logic/launch/steps/TextPrint.cpp b/libraries/logic/launch/steps/TextPrint.cpp
deleted file mode 100644
index f307b1fd..00000000
--- a/libraries/logic/launch/steps/TextPrint.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "TextPrint.h"
-
-TextPrint::TextPrint(LaunchTask * parent, const QStringList &lines, MessageLevel::Enum level) : LaunchStep(parent)
-{
- m_lines = lines;
- m_level = level;
-}
-TextPrint::TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level) : LaunchStep(parent)
-{
- m_lines.append(line);
- m_level = level;
-}
-
-void TextPrint::executeTask()
-{
- emit logLines(m_lines, m_level);
- emitSucceeded();
-}
-
-bool TextPrint::canAbort() const
-{
- return true;
-}
-
-bool TextPrint::abort()
-{
- emitFailed("Aborted.");
- return true;
-}
diff --git a/libraries/logic/launch/steps/TextPrint.h b/libraries/logic/launch/steps/TextPrint.h
deleted file mode 100644
index fdd9014a..00000000
--- a/libraries/logic/launch/steps/TextPrint.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
-#include <java/JavaChecker.h>
-
-#include "multimc_logic_export.h"
-
-/*
- * FIXME: maybe do not export
- */
-
-class MULTIMC_LOGIC_EXPORT TextPrint: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit TextPrint(LaunchTask *parent, const QStringList &lines, MessageLevel::Enum level);
- explicit TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level);
- virtual ~TextPrint(){};
-
- virtual void executeTask();
- virtual bool canAbort() const;
- virtual bool abort();
-
-private:
- QStringList m_lines;
- MessageLevel::Enum m_level;
-};
diff --git a/libraries/logic/launch/steps/Update.cpp b/libraries/logic/launch/steps/Update.cpp
deleted file mode 100644
index 4901f001..00000000
--- a/libraries/logic/launch/steps/Update.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 2013-2015 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 "Update.h"
-#include <launch/LaunchTask.h>
-
-void Update::executeTask()
-{
- m_updateTask = m_parent->instance()->createUpdateTask();
- if(m_updateTask)
- {
- connect(m_updateTask.get(), SIGNAL(finished()), this, SLOT(updateFinished()));
- connect(m_updateTask.get(), &Task::progress, this, &Task::setProgress);
- connect(m_updateTask.get(), &Task::status, this, &Task::setStatus);
- emit progressReportingRequest();
- return;
- }
- emitSucceeded();
-}
-
-void Update::proceed()
-{
- m_updateTask->start();
-}
-
-void Update::updateFinished()
-{
- if(m_updateTask->successful())
- {
- emitSucceeded();
- }
- else
- {
- QString reason = tr("Instance update failed because: %1.\n\n").arg(m_updateTask->failReason());
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- }
-}
diff --git a/libraries/logic/launch/steps/Update.h b/libraries/logic/launch/steps/Update.h
deleted file mode 100644
index 14928253..00000000
--- a/libraries/logic/launch/steps/Update.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <launch/LaunchStep.h>
-#include <launch/LoggedProcess.h>
-#include <java/JavaChecker.h>
-
-// FIXME: stupid. should be defined by the instance type? or even completely abstracted away...
-class Update: public LaunchStep
-{
- Q_OBJECT
-public:
- explicit Update(LaunchTask *parent):LaunchStep(parent) {};
- virtual ~Update() {};
-
- virtual void executeTask();
- virtual bool canAbort() const
- {
- return false;
- }
- virtual void proceed();
-private slots:
- void updateFinished();
-
-private:
- std::shared_ptr<Task> m_updateTask;
-};
diff --git a/libraries/logic/minecraft/AssetsUtils.cpp b/libraries/logic/minecraft/AssetsUtils.cpp
deleted file mode 100644
index 7a525abe..00000000
--- a/libraries/logic/minecraft/AssetsUtils.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright 2013-2015 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 <QFileInfo>
-#include <QDir>
-#include <QDirIterator>
-#include <QCryptographicHash>
-#include <QJsonParseError>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QVariant>
-#include <QDebug>
-
-#include "AssetsUtils.h"
-#include "FileSystem.h"
-#include "net/MD5EtagDownload.h"
-
-namespace AssetsUtils
-{
-
-/*
- * Returns true on success, with index populated
- * index is undefined otherwise
- */
-bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
-{
- /*
- {
- "objects": {
- "icons/icon_16x16.png": {
- "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
- "size": 3665
- },
- ...
- }
- }
- }
- */
-
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::ReadOnly))
- {
- qCritical() << "Failed to read assets index file" << path;
- return false;
- }
- index->id = assetsId;
-
- // Read the file and close it.
- QByteArray jsonData = file.readAll();
- file.close();
-
- QJsonParseError parseError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
-
- // Fail if the JSON is invalid.
- if (parseError.error != QJsonParseError::NoError)
- {
- qCritical() << "Failed to parse assets index file:" << parseError.errorString()
- << "at offset " << QString::number(parseError.offset);
- return false;
- }
-
- // Make sure the root is an object.
- if (!jsonDoc.isObject())
- {
- qCritical() << "Invalid assets index JSON: Root should be an array.";
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- QJsonValue isVirtual = root.value("virtual");
- if (!isVirtual.isUndefined())
- {
- index->isVirtual = isVirtual.toBool(false);
- }
-
- QJsonValue objects = root.value("objects");
- QVariantMap map = objects.toVariant().toMap();
-
- for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
- {
- // qDebug() << iter.key();
-
- QVariant variant = iter.value();
- QVariantMap nested_objects = variant.toMap();
-
- AssetObject object;
-
- for (QVariantMap::const_iterator nested_iter = nested_objects.begin();
- nested_iter != nested_objects.end(); ++nested_iter)
- {
- // qDebug() << nested_iter.key() << nested_iter.value().toString();
- QString key = nested_iter.key();
- QVariant value = nested_iter.value();
-
- if (key == "hash")
- {
- object.hash = value.toString();
- }
- else if (key == "size")
- {
- object.size = value.toDouble();
- }
- }
-
- index->objects.insert(iter.key(), object);
- }
-
- return true;
-}
-
-QDir reconstructAssets(QString assetsId)
-{
- QDir assetsDir = QDir("assets/");
- QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes"));
- QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects"));
- QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual"));
-
- QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json");
- QFile indexFile(indexPath);
- QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId));
-
- if (!indexFile.exists())
- {
- qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets";
- return virtualRoot;
- }
-
- qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path()
- << objectDir.path() << virtualDir.path() << virtualRoot.path();
-
- AssetsIndex index;
- bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index);
-
- if (loadAssetsIndex && index.isVirtual)
- {
- qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path();
-
- for (QString map : index.objects.keys())
- {
- AssetObject asset_object = index.objects.value(map);
- QString target_path = FS::PathCombine(virtualRoot.path(), map);
- QFile target(target_path);
-
- QString tlk = asset_object.hash.left(2);
-
- QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash);
- QFile original(original_path);
- if (!original.exists())
- continue;
- if (!target.exists())
- {
- QFileInfo info(target_path);
- QDir target_dir = info.dir();
- // qDebug() << target_dir;
- if (!target_dir.exists())
- QDir("").mkpath(target_dir.path());
-
- bool couldCopy = original.copy(target_path);
- qDebug() << " Copying" << original_path << "to" << target_path
- << QString::number(couldCopy); // << original.errorString();
- }
- }
-
- // TODO: Write last used time to virtualRoot/.lastused
- }
-
- return virtualRoot;
-}
-
-}
-
-NetActionPtr AssetObject::getDownloadAction()
-{
- QFileInfo objectFile(getLocalPath());
- if ((!objectFile.isFile()) || (objectFile.size() != size))
- {
- auto objectDL = MD5EtagDownload::make(getUrl(), objectFile.filePath());
- objectDL->m_total_progress = size;
- return objectDL;
- }
- return nullptr;
-}
-
-QString AssetObject::getLocalPath()
-{
- return "assets/objects/" + getRelPath();
-}
-
-QUrl AssetObject::getUrl()
-{
- return QUrl("http://resources.download.minecraft.net/" + getRelPath());
-}
-
-QString AssetObject::getRelPath()
-{
- return hash.left(2) + "/" + hash;
-}
-
-NetJobPtr AssetsIndex::getDownloadJob()
-{
- auto job = new NetJob(QObject::tr("Assets for %1").arg(id));
- for (auto &object : objects.values())
- {
- auto dl = object.getDownloadAction();
- if(dl)
- {
- job->addNetAction(dl);
- }
- }
- if(job->size())
- return job;
- return nullptr;
-}
diff --git a/libraries/logic/minecraft/AssetsUtils.h b/libraries/logic/minecraft/AssetsUtils.h
deleted file mode 100644
index 90251c2d..00000000
--- a/libraries/logic/minecraft/AssetsUtils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-#include <QMap>
-#include "net/NetAction.h"
-#include "net/NetJob.h"
-
-struct AssetObject
-{
- QString getRelPath();
- QUrl getUrl();
- QString getLocalPath();
- NetActionPtr getDownloadAction();
-
- QString hash;
- qint64 size;
-};
-
-struct AssetsIndex
-{
- NetJobPtr getDownloadJob();
-
- QString id;
- QMap<QString, AssetObject> objects;
- bool isVirtual = false;
-};
-
-namespace AssetsUtils
-{
-bool loadAssetsIndexJson(QString id, QString file, AssetsIndex* index);
-/// Reconstruct a virtual assets folder for the given assets ID and return the folder
-QDir reconstructAssets(QString assetsId);
-}
diff --git a/libraries/logic/minecraft/GradleSpecifier.h b/libraries/logic/minecraft/GradleSpecifier.h
deleted file mode 100644
index 18308537..00000000
--- a/libraries/logic/minecraft/GradleSpecifier.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QStringList>
-#include "DefaultVariable.h"
-
-struct GradleSpecifier
-{
- GradleSpecifier()
- {
- m_valid = false;
- }
- GradleSpecifier(QString value)
- {
- operator=(value);
- }
- GradleSpecifier & operator =(const QString & value)
- {
- /*
- org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar
- DEBUG 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar"
- DEBUG 1 "org.gradle.test.classifiers"
- DEBUG 2 "service"
- DEBUG 3 "1.0"
- DEBUG 4 ":jdk15"
- DEBUG 5 "jdk15"
- DEBUG 6 "@jar"
- DEBUG 7 "jar"
- */
- QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(:([^:@]+))?" "(@([^:@]+))?");
- m_valid = matcher.exactMatch(value);
- auto elements = matcher.capturedTexts();
- m_groupId = elements[1];
- m_artifactId = elements[2];
- m_version = elements[3];
- m_classifier = elements[5];
- if(!elements[7].isEmpty())
- {
- m_extension = elements[7];
- }
- return *this;
- }
- operator QString() const
- {
- if(!m_valid)
- return "INVALID";
- QString retval = m_groupId + ":" + m_artifactId + ":" + m_version;
- if(!m_classifier.isEmpty())
- {
- retval += ":" + m_classifier;
- }
- if(m_extension.isExplicit())
- {
- retval += "@" + m_extension;
- }
- return retval;
- }
- QString toPath() const
- {
- if(!m_valid)
- return "INVALID";
- QString path = m_groupId;
- path.replace('.', '/');
- path += '/' + m_artifactId + '/' + m_version + '/' + m_artifactId + '-' + m_version;
- if(!m_classifier.isEmpty())
- {
- path += "-" + m_classifier;
- }
- path += "." + m_extension;
- return path;
- }
- inline bool valid() const
- {
- return m_valid;
- }
- inline QString version() const
- {
- return m_version;
- }
- inline QString groupId() const
- {
- return m_groupId;
- }
- inline QString artifactId() const
- {
- return m_artifactId;
- }
- inline void setClassifier(const QString & classifier)
- {
- m_classifier = classifier;
- }
- inline QString classifier() const
- {
- return m_classifier;
- }
- inline QString extension() const
- {
- return m_extension;
- }
- inline QString artifactPrefix() const
- {
- return m_groupId + ":" + m_artifactId;
- }
- bool matchName(const GradleSpecifier & other) const
- {
- return other.artifactId() == artifactId() && other.groupId() == groupId();
- }
- bool operator==(const GradleSpecifier & other) const
- {
- if(m_groupId != other.m_groupId)
- return false;
- if(m_artifactId != other.m_artifactId)
- return false;
- if(m_version != other.m_version)
- return false;
- if(m_classifier != other.m_classifier)
- return false;
- if(m_extension != other.m_extension)
- return false;
- return true;
- }
-private:
- QString m_groupId;
- QString m_artifactId;
- QString m_version;
- QString m_classifier;
- DefaultVariable<QString> m_extension = DefaultVariable<QString>("jar");
- bool m_valid = false;
-};
diff --git a/libraries/logic/minecraft/JarMod.h b/libraries/logic/minecraft/JarMod.h
deleted file mode 100644
index 42d05da9..00000000
--- a/libraries/logic/minecraft/JarMod.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-#include <QString>
-#include <QJsonObject>
-#include <memory>
-class Jarmod;
-typedef std::shared_ptr<Jarmod> JarmodPtr;
-class Jarmod
-{
-public: /* data */
- QString name;
- QString originalName;
-};
diff --git a/libraries/logic/minecraft/Library.cpp b/libraries/logic/minecraft/Library.cpp
deleted file mode 100644
index 922db84e..00000000
--- a/libraries/logic/minecraft/Library.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-#include "Library.h"
-#include <net/CacheDownload.h>
-#include <minecraft/forge/ForgeXzDownload.h>
-#include <Env.h>
-#include <FileSystem.h>
-
-void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& native, QStringList& native32, QStringList& native64) const
-{
- auto actualPath = [&](QString relPath)
- {
- QFileInfo out(FS::PathCombine(storagePrefix(), relPath));
- return out.absoluteFilePath();
- };
- if(m_mojangDownloads)
- {
- if(m_mojangDownloads->artifact)
- {
- auto artifact = m_mojangDownloads->artifact;
- jar += actualPath(artifact->path);
- }
- if(!isNative())
- return;
- if(m_nativeClassifiers.contains(system))
- {
- auto nativeClassifier = m_nativeClassifiers[system];
- if(nativeClassifier.contains("${arch}"))
- {
- auto nat32Classifier = nativeClassifier;
- nat32Classifier.replace("${arch}", "32");
- auto nat64Classifier = nativeClassifier;
- nat64Classifier.replace("${arch}", "64");
- auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
- if(nat32info)
- native32 += actualPath(nat32info->path);
- auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
- if(nat64info)
- native64 += actualPath(nat64info->path);
- }
- else
- {
- native += actualPath(m_mojangDownloads->getDownloadInfo(nativeClassifier)->path);
- }
- }
- }
- else
- {
- QString raw_storage = storageSuffix(system);
- if(isNative())
- {
- if (raw_storage.contains("${arch}"))
- {
- auto nat32Storage = raw_storage;
- nat32Storage.replace("${arch}", "32");
- auto nat64Storage = raw_storage;
- nat64Storage.replace("${arch}", "64");
- native32 += actualPath(nat32Storage);
- native64 += actualPath(nat64Storage);
- }
- else
- {
- native += actualPath(raw_storage);
- }
- }
- else
- {
- jar += actualPath(raw_storage);
- }
- }
-}
-
-QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, QStringList &failedFiles) const
-{
- QList<NetActionPtr> out;
- bool isLocal = (hint() == "local");
- bool isForge = (hint() == "forge-pack-xz");
-
- auto add_download = [&](QString storage, QString dl)
- {
- auto entry = cache->resolveEntry("libraries", storage);
- if (!entry->isStale())
- return true;
- if(isLocal)
- {
- QFileInfo fileinfo(entry->getFullPath());
- if(!fileinfo.exists())
- {
- failedFiles.append(entry->getFullPath());
- return false;
- }
- return true;
- }
- if (isForge)
- {
- out.append(ForgeXzDownload::make(storage, entry));
- }
- else
- {
- out.append(CacheDownload::make(dl, entry));
- }
- return true;
- };
-
- if(m_mojangDownloads)
- {
- if(m_mojangDownloads->artifact)
- {
- auto artifact = m_mojangDownloads->artifact;
- add_download(artifact->path, artifact->url);
- }
- if(m_nativeClassifiers.contains(system))
- {
- auto nativeClassifier = m_nativeClassifiers[system];
- if(nativeClassifier.contains("${arch}"))
- {
- auto nat32Classifier = nativeClassifier;
- nat32Classifier.replace("${arch}", "32");
- auto nat64Classifier = nativeClassifier;
- nat64Classifier.replace("${arch}", "64");
- auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
- if(nat32info)
- add_download(nat32info->path, nat32info->url);
- auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
- if(nat64info)
- add_download(nat64info->path, nat64info->url);
- }
- else
- {
- auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier);
- if(info)
- {
- add_download(info->path, info->url);
- }
- }
- }
- }
- else
- {
- QString raw_storage = storageSuffix(system);
- auto raw_dl = [&](){
- if (!m_absoluteURL.isEmpty())
- {
- return m_absoluteURL;
- }
-
- if (m_repositoryURL.isEmpty())
- {
- return QString("https://" + URLConstants::LIBRARY_BASE) + raw_storage;
- }
-
- if(m_repositoryURL.endsWith('/'))
- {
- return m_repositoryURL + raw_storage;
- }
- else
- {
- return m_repositoryURL + QChar('/') + raw_storage;
- }
- }();
- if (raw_storage.contains("${arch}"))
- {
- QString cooked_storage = raw_storage;
- QString cooked_dl = raw_dl;
- add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"));
- cooked_storage = raw_storage;
- cooked_dl = raw_dl;
- add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"));
- }
- else
- {
- add_download(raw_storage, raw_dl);
- }
- }
- return out;
-}
-
-bool Library::isActive() const
-{
- bool result = true;
- if (m_rules.empty())
- {
- result = true;
- }
- else
- {
- RuleAction ruleResult = Disallow;
- for (auto rule : m_rules)
- {
- RuleAction temp = rule->apply(this);
- if (temp != Defer)
- ruleResult = temp;
- }
- result = result && (ruleResult == Allow);
- }
- if (isNative())
- {
- result = result && m_nativeClassifiers.contains(currentSystem);
- }
- return result;
-}
-
-void Library::setStoragePrefix(QString prefix)
-{
- m_storagePrefix = prefix;
-}
-
-QString Library::defaultStoragePrefix()
-{
- return "libraries/";
-}
-
-QString Library::storagePrefix() const
-{
- if(m_storagePrefix.isEmpty())
- {
- return defaultStoragePrefix();
- }
- return m_storagePrefix;
-}
-
-QString Library::storageSuffix(OpSys system) const
-{
- // non-native? use only the gradle specifier
- if (!isNative())
- {
- return m_name.toPath();
- }
-
- // otherwise native, override classifiers. Mojang HACK!
- GradleSpecifier nativeSpec = m_name;
- if (m_nativeClassifiers.contains(system))
- {
- nativeSpec.setClassifier(m_nativeClassifiers[system]);
- }
- else
- {
- nativeSpec.setClassifier("INVALID");
- }
- return nativeSpec.toPath();
-}
diff --git a/libraries/logic/minecraft/Library.h b/libraries/logic/minecraft/Library.h
deleted file mode 100644
index fdce93f3..00000000
--- a/libraries/logic/minecraft/Library.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#pragma once
-#include <QString>
-#include <net/NetAction.h>
-#include <QPair>
-#include <QList>
-#include <QStringList>
-#include <QMap>
-#include <QDir>
-#include <QUrl>
-#include <memory>
-
-#include "Rule.h"
-#include "minecraft/OpSys.h"
-#include "GradleSpecifier.h"
-#include "net/URLConstants.h"
-#include "MojangDownloadInfo.h"
-
-#include "multimc_logic_export.h"
-
-class Library;
-
-typedef std::shared_ptr<Library> LibraryPtr;
-
-class MULTIMC_LOGIC_EXPORT Library
-{
- friend class OneSixVersionFormat;
- friend class MojangVersionFormat;
- friend class LibraryTest;
-public:
- Library()
- {
- }
- Library(const QString &name)
- {
- m_name = name;
- }
- /// limited copy without some data. TODO: why?
- static LibraryPtr limitedCopy(LibraryPtr base)
- {
- auto newlib = std::make_shared<Library>();
- newlib->m_name = base->m_name;
- newlib->m_repositoryURL = base->m_repositoryURL;
- newlib->m_hint = base->m_hint;
- newlib->m_absoluteURL = base->m_absoluteURL;
- newlib->m_extractExcludes = base->m_extractExcludes;
- newlib->m_nativeClassifiers = base->m_nativeClassifiers;
- newlib->m_rules = base->m_rules;
- newlib->m_storagePrefix = base->m_storagePrefix;
- newlib->m_mojangDownloads = base->m_mojangDownloads;
- return newlib;
- }
-
-public: /* methods */
- /// Returns the raw name field
- const GradleSpecifier & rawName() const
- {
- return m_name;
- }
-
- void setRawName(const GradleSpecifier & spec)
- {
- m_name = spec;
- }
-
- void setClassifier(const QString & spec)
- {
- m_name.setClassifier(spec);
- }
-
- /// returns the full group and artifact prefix
- QString artifactPrefix() const
- {
- return m_name.artifactPrefix();
- }
-
- /// get the artifact ID
- QString artifactId() const
- {
- return m_name.artifactId();
- }
-
- /// get the artifact version
- QString version() const
- {
- return m_name.version();
- }
-
- /// Returns true if the library is native
- bool isNative() const
- {
- return m_nativeClassifiers.size() != 0;
- }
-
- void setStoragePrefix(QString prefix = QString());
-
- /// Set the url base for downloads
- void setRepositoryURL(const QString &base_url)
- {
- m_repositoryURL = base_url;
- }
-
- void getApplicableFiles(OpSys system, QStringList & jar, QStringList & native, QStringList & native32, QStringList & native64) const;
-
- void setAbsoluteUrl(const QString &absolute_url)
- {
- m_absoluteURL = absolute_url;
- }
-
- void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info)
- {
- m_mojangDownloads = info;
- }
-
- void setHint(const QString &hint)
- {
- m_hint = hint;
- }
-
- /// Set the load rules
- void setRules(QList<std::shared_ptr<Rule>> rules)
- {
- m_rules = rules;
- }
-
- /// Returns true if the library should be loaded (or extracted, in case of natives)
- bool isActive() const;
-
- // Get a list of downloads for this library
- QList<NetActionPtr> getDownloads(OpSys system, class HttpMetaCache * cache, QStringList &failedFiles) const;
-
-private: /* methods */
- /// the default storage prefix used by MultiMC
- static QString defaultStoragePrefix();
-
- /// Get the prefix - root of the storage to be used
- QString storagePrefix() const;
-
- /// Get the relative path where the library should be saved
- QString storageSuffix(OpSys system) const;
-
- QString hint() const
- {
- return m_hint;
- }
-
-protected: /* data */
- /// the basic gradle dependency specifier.
- GradleSpecifier m_name;
-
- /// DEPRECATED URL prefix of the maven repo where the file can be downloaded
- QString m_repositoryURL;
-
- /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined
- QString m_absoluteURL;
-
- /**
- * MultiMC-specific type hint - modifies how the library is treated
- */
- QString m_hint;
-
- /**
- * storage - by default the local libraries folder in multimc, but could be elsewhere
- * MultiMC specific, because of FTB.
- */
- QString m_storagePrefix;
-
- /// true if the library had an extract/excludes section (even empty)
- bool m_hasExcludes = false;
-
- /// a list of files that shouldn't be extracted from the library
- QStringList m_extractExcludes;
-
- /// native suffixes per OS
- QMap<OpSys, QString> m_nativeClassifiers;
-
- /// true if the library had a rules section (even empty)
- bool applyRules = false;
-
- /// rules associated with the library
- QList<std::shared_ptr<Rule>> m_rules;
-
- /// MOJANG: container with Mojang style download info
- MojangLibraryDownloadInfo::Ptr m_mojangDownloads;
-};
diff --git a/libraries/logic/minecraft/MinecraftInstance.cpp b/libraries/logic/minecraft/MinecraftInstance.cpp
deleted file mode 100644
index 405ccd26..00000000
--- a/libraries/logic/minecraft/MinecraftInstance.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-#include "MinecraftInstance.h"
-#include <settings/Setting.h>
-#include "settings/SettingsObject.h"
-#include "Env.h"
-#include "minecraft/MinecraftVersionList.h"
-#include <MMCStrings.h>
-#include <pathmatcher/RegexpMatcher.h>
-#include <pathmatcher/MultiMatcher.h>
-#include <FileSystem.h>
-#include <java/JavaVersion.h>
-
-#define IBUS "@im=ibus"
-
-// all of this because keeping things compatible with deprecated old settings
-// if either of the settings {a, b} is true, this also resolves to true
-class OrSetting : public Setting
-{
- Q_OBJECT
-public:
- OrSetting(QString id, std::shared_ptr<Setting> a, std::shared_ptr<Setting> b)
- :Setting({id}, false), m_a(a), m_b(b)
- {
- }
- virtual QVariant get() const
- {
- bool a = m_a->get().toBool();
- bool b = m_b->get().toBool();
- return a || b;
- }
- virtual void reset() {}
- virtual void set(QVariant value) {}
-private:
- std::shared_ptr<Setting> m_a;
- std::shared_ptr<Setting> m_b;
-};
-
-MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : BaseInstance(globalSettings, settings, rootDir)
-{
- // Java Settings
- auto javaOverride = m_settings->registerSetting("OverrideJava", false);
- auto locationOverride = m_settings->registerSetting("OverrideJavaLocation", false);
- auto argsOverride = m_settings->registerSetting("OverrideJavaArgs", false);
-
- // combinations
- auto javaOrLocation = std::make_shared<OrSetting>("JavaOrLocationOverride", javaOverride, locationOverride);
- auto javaOrArgs = std::make_shared<OrSetting>("JavaOrArgsOverride", javaOverride, argsOverride);
-
- m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
- m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
-
- // special!
- m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
- m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
-
- // Window Size
- auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
- m_settings->registerOverride(globalSettings->getSetting("LaunchMaximized"), windowSetting);
- m_settings->registerOverride(globalSettings->getSetting("MinecraftWinWidth"), windowSetting);
- m_settings->registerOverride(globalSettings->getSetting("MinecraftWinHeight"), windowSetting);
-
- // Memory
- auto memorySetting = m_settings->registerSetting("OverrideMemory", false);
- m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc"), memorySetting);
- m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
- m_settings->registerOverride(globalSettings->getSetting("PermGen"), memorySetting);
-}
-
-QString MinecraftInstance::minecraftRoot() const
-{
- QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
- QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
-
- if (dotMCDir.exists() && !mcDir.exists())
- return dotMCDir.filePath();
- else
- return mcDir.filePath();
-}
-
-std::shared_ptr< BaseVersionList > MinecraftInstance::versionList() const
-{
- return ENV.getVersionList("net.minecraft");
-}
-
-QStringList MinecraftInstance::javaArguments() const
-{
- QStringList args;
-
- // custom args go first. we want to override them if we have our own here.
- args.append(extraArguments());
-
- // OSX dock icon and name
-#ifdef Q_OS_MAC
- args << "-Xdock:icon=icon.png";
- args << QString("-Xdock:name=\"%1\"").arg(windowTitle());
-#endif
-
- // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767
-#ifdef Q_OS_WIN32
- args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
- "minecraft.exe.heapdump");
-#endif
-
- args << QString("-Xms%1m").arg(settings()->get("MinMemAlloc").toInt());
- args << QString("-Xmx%1m").arg(settings()->get("MaxMemAlloc").toInt());
-
- // No PermGen in newer java.
- JavaVersion javaVersion(settings()->get("JavaVersion").toString());
- if(javaVersion.requiresPermGen())
- {
- auto permgen = settings()->get("PermGen").toInt();
- if (permgen != 64)
- {
- args << QString("-XX:PermSize=%1m").arg(permgen);
- }
- }
-
- args << "-Duser.language=en";
- args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
-
- return args;
-}
-
-QMap<QString, QString> MinecraftInstance::getVariables() const
-{
- QMap<QString, QString> out;
- out.insert("INST_NAME", name());
- out.insert("INST_ID", id());
- out.insert("INST_DIR", QDir(instanceRoot()).absolutePath());
- out.insert("INST_MC_DIR", QDir(minecraftRoot()).absolutePath());
- out.insert("INST_JAVA", settings()->get("JavaPath").toString());
- out.insert("INST_JAVA_ARGS", javaArguments().join(' '));
- return out;
-}
-
-static QString processLD_LIBRARY_PATH(const QString & LD_LIBRARY_PATH)
-{
- QDir mmcBin(QCoreApplication::applicationDirPath());
- auto items = LD_LIBRARY_PATH.split(':');
- QStringList final;
- for(auto & item: items)
- {
- QDir test(item);
- if(test == mmcBin)
- {
- qDebug() << "Env:LD_LIBRARY_PATH ignoring path" << item;
- continue;
- }
- final.append(item);
- }
- return final.join(':');
-}
-
-QProcessEnvironment MinecraftInstance::createEnvironment()
-{
- // prepare the process environment
- QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
- QProcessEnvironment env;
-
- QStringList ignored =
- {
- "JAVA_ARGS",
- "CLASSPATH",
- "CONFIGPATH",
- "JAVA_HOME",
- "JRE_HOME",
- "_JAVA_OPTIONS",
- "JAVA_OPTIONS",
- "JAVA_TOOL_OPTIONS"
- };
- for(auto key: rawenv.keys())
- {
- auto value = rawenv.value(key);
- // filter out dangerous java crap
- if(ignored.contains(key))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
- // filter MultiMC-related things
- if(key.startsWith("QT_"))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
-#ifdef Q_OS_LINUX
- // Do not pass LD_* variables to java. They were intended for MultiMC
- if(key.startsWith("LD_"))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
- // Strip IBus
- // IBus is a Linux IME framework. For some reason, it breaks MC?
- if (key == "XMODIFIERS" && value.contains(IBUS))
- {
- QString save = value;
- value.replace(IBUS, "");
- qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
- }
- if(key == "GAME_PRELOAD")
- {
- env.insert("LD_PRELOAD", value);
- continue;
- }
- if(key == "GAME_LIBRARY_PATH")
- {
- env.insert("LD_LIBRARY_PATH", processLD_LIBRARY_PATH(value));
- continue;
- }
-#endif
- qDebug() << "Env: " << key << value;
- env.insert(key, value);
- }
-#ifdef Q_OS_LINUX
- // HACK: Workaround for QTBUG42500
- if(!env.contains("LD_LIBRARY_PATH"))
- {
- env.insert("LD_LIBRARY_PATH", "");
- }
-#endif
-
- // export some infos
- auto variables = getVariables();
- for (auto it = variables.begin(); it != variables.end(); ++it)
- {
- env.insert(it.key(), it.value());
- }
- return env;
-}
-
-QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSessionPtr session)
-{
- if(!session)
- {
- return QMap<QString, QString>();
- }
- auto & sessionRef = *session.get();
- QMap<QString, QString> filter;
- auto addToFilter = [&filter](QString key, QString value)
- {
- if(key.trimmed().size())
- {
- filter[key] = value;
- }
- };
- if (sessionRef.session != "-")
- {
- addToFilter(sessionRef.session, tr("<SESSION ID>"));
- }
- addToFilter(sessionRef.access_token, tr("<ACCESS TOKEN>"));
- addToFilter(sessionRef.client_token, tr("<CLIENT TOKEN>"));
- addToFilter(sessionRef.uuid, tr("<PROFILE ID>"));
- addToFilter(sessionRef.player_name, tr("<PROFILE NAME>"));
-
- auto i = sessionRef.u.properties.begin();
- while (i != sessionRef.u.properties.end())
- {
- addToFilter(i.value(), "<" + i.key().toUpper() + ">");
- ++i;
- }
- return filter;
-}
-
-MessageLevel::Enum MinecraftInstance::guessLevel(const QString &line, MessageLevel::Enum level)
-{
- QRegularExpression re("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
- auto match = re.match(line);
- if(match.hasMatch())
- {
- // New style logs from log4j
- QString timestamp = match.captured("timestamp");
- QString levelStr = match.captured("level");
- if(levelStr == "INFO")
- level = MessageLevel::Message;
- if(levelStr == "WARN")
- level = MessageLevel::Warning;
- if(levelStr == "ERROR")
- level = MessageLevel::Error;
- if(levelStr == "FATAL")
- level = MessageLevel::Fatal;
- if(levelStr == "TRACE" || levelStr == "DEBUG")
- level = MessageLevel::Debug;
- }
- else
- {
- // Old style forge logs
- if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") ||
- line.contains("[FINER]") || line.contains("[FINEST]"))
- level = MessageLevel::Message;
- if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
- level = MessageLevel::Error;
- if (line.contains("[WARNING]"))
- level = MessageLevel::Warning;
- if (line.contains("[DEBUG]"))
- level = MessageLevel::Debug;
- }
- if (line.contains("overwriting existing"))
- return MessageLevel::Fatal;
- //NOTE: this diverges from the real regexp. no unicode, the first section is + instead of *
- static const QString javaSymbol = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
- if (line.contains("Exception in thread")
- || line.contains(QRegularExpression("\\s+at " + javaSymbol))
- || line.contains(QRegularExpression("Caused by: " + javaSymbol))
- || line.contains(QRegularExpression("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)"))
- || line.contains(QRegularExpression("... \\d+ more$"))
- )
- return MessageLevel::Error;
- return level;
-}
-
-IPathMatcher::Ptr MinecraftInstance::getLogFileMatcher()
-{
- auto combined = std::make_shared<MultiMatcher>();
- combined->add(std::make_shared<RegexpMatcher>(".*\\.log(\\.[0-9]*)?(\\.gz)?$"));
- combined->add(std::make_shared<RegexpMatcher>("crash-.*\\.txt"));
- combined->add(std::make_shared<RegexpMatcher>("IDMap dump.*\\.txt$"));
- combined->add(std::make_shared<RegexpMatcher>("ModLoader\\.txt(\\..*)?$"));
- return combined;
-}
-
-QString MinecraftInstance::getLogFileRoot()
-{
- return minecraftRoot();
-}
-
-QString MinecraftInstance::prettifyTimeDuration(int64_t duration)
-{
- int seconds = (int) (duration % 60);
- duration /= 60;
- int minutes = (int) (duration % 60);
- duration /= 60;
- int hours = (int) (duration % 24);
- int days = (int) (duration / 24);
- if((hours == 0)&&(days == 0))
- {
- return tr("%1m %2s").arg(minutes).arg(seconds);
- }
- if (days == 0)
- {
- return tr("%1h %2m").arg(hours).arg(minutes);
- }
- return tr("%1d %2h %3m").arg(days).arg(hours).arg(minutes);
-}
-
-QString MinecraftInstance::getStatusbarDescription()
-{
- QStringList traits;
- if (flags() & VersionBrokenFlag)
- {
- traits.append(tr("broken"));
- }
-
- QString description;
- description.append(tr("Minecraft %1 (%2)").arg(intendedVersionId()).arg(typeName()));
- if(totalTimePlayed() > 0)
- {
- description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
- }
- /*
- if(traits.size())
- {
- description.append(QString(" (%1)").arg(traits.join(", ")));
- }
- */
- return description;
-}
-
-#include "MinecraftInstance.moc"
diff --git a/libraries/logic/minecraft/MinecraftInstance.h b/libraries/logic/minecraft/MinecraftInstance.h
deleted file mode 100644
index cd3a8d90..00000000
--- a/libraries/logic/minecraft/MinecraftInstance.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-#include "BaseInstance.h"
-#include "minecraft/Mod.h"
-#include <QProcess>
-
-#include "multimc_logic_export.h"
-
-class ModList;
-class WorldList;
-
-class MULTIMC_LOGIC_EXPORT MinecraftInstance: public BaseInstance
-{
-public:
- MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~MinecraftInstance() {};
-
- /// Path to the instance's minecraft directory.
- QString minecraftRoot() const;
-
- ////// Mod Lists //////
- virtual std::shared_ptr<ModList> resourcePackList() const
- {
- return nullptr;
- }
- virtual std::shared_ptr<ModList> texturePackList() const
- {
- return nullptr;
- }
- virtual std::shared_ptr<WorldList> worldList() const
- {
- return nullptr;
- }
- /// get all jar mods applicable to this instance's jar
- virtual QList<Mod> getJarMods() const
- {
- return QList<Mod>();
- }
-
- /// get the launch script to be used with this
- virtual QString createLaunchScript(AuthSessionPtr session) = 0;
-
- //FIXME: nuke?
- virtual std::shared_ptr<BaseVersionList> versionList() const override;
-
- /// get arguments passed to java
- QStringList javaArguments() const;
-
- /// get variables for launch command variable substitution/environment
- virtual QMap<QString, QString> getVariables() const override;
-
- /// create an environment for launching processes
- virtual QProcessEnvironment createEnvironment() override;
-
- /// guess log level from a line of minecraft log
- virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level) override;
-
- virtual IPathMatcher::Ptr getLogFileMatcher() override;
-
- virtual QString getLogFileRoot() override;
-
- virtual QString getStatusbarDescription() override;
-
-protected:
- QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
-private:
- QString prettifyTimeDuration(int64_t duration);
-};
-
-typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr;
diff --git a/libraries/logic/minecraft/MinecraftProfile.cpp b/libraries/logic/minecraft/MinecraftProfile.cpp
deleted file mode 100644
index 70d0cee4..00000000
--- a/libraries/logic/minecraft/MinecraftProfile.cpp
+++ /dev/null
@@ -1,610 +0,0 @@
-/* Copyright 2013-2015 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 <QFile>
-#include <QCryptographicHash>
-#include <Version.h>
-#include <QDir>
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QDebug>
-
-#include "minecraft/MinecraftProfile.h"
-#include "ProfileUtils.h"
-#include "ProfileStrategy.h"
-#include "Exception.h"
-
-MinecraftProfile::MinecraftProfile(ProfileStrategy *strategy)
- : QAbstractListModel()
-{
- setStrategy(strategy);
- clear();
-}
-
-void MinecraftProfile::setStrategy(ProfileStrategy* strategy)
-{
- Q_ASSERT(strategy != nullptr);
-
- if(m_strategy != nullptr)
- {
- delete m_strategy;
- m_strategy = nullptr;
- }
- m_strategy = strategy;
- m_strategy->profile = this;
-}
-
-ProfileStrategy* MinecraftProfile::strategy()
-{
- return m_strategy;
-}
-
-void MinecraftProfile::reload()
-{
- beginResetModel();
- m_strategy->load();
- reapplyPatches();
- endResetModel();
-}
-
-void MinecraftProfile::clear()
-{
- m_minecraftVersion.clear();
- m_minecraftVersionType.clear();
- m_minecraftAssets.reset();
- m_minecraftArguments.clear();
- m_tweakers.clear();
- m_mainClass.clear();
- m_appletClass.clear();
- m_libraries.clear();
- m_traits.clear();
- m_jarMods.clear();
- mojangDownloads.clear();
- m_problemSeverity = ProblemSeverity::PROBLEM_NONE;
-}
-
-void MinecraftProfile::clearPatches()
-{
- beginResetModel();
- m_patches.clear();
- endResetModel();
-}
-
-void MinecraftProfile::appendPatch(ProfilePatchPtr patch)
-{
- int index = m_patches.size();
- beginInsertRows(QModelIndex(), index, index);
- m_patches.append(patch);
- endInsertRows();
-}
-
-bool MinecraftProfile::remove(const int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isRemovable())
- {
- qDebug() << "Patch" << patch->getID() << "is non-removable";
- return false;
- }
-
- if(!m_strategy->removePatch(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be removed";
- return false;
- }
-
- beginRemoveRows(QModelIndex(), index, index);
- m_patches.removeAt(index);
- endRemoveRows();
- reapplyPatches();
- saveCurrentOrder();
- return true;
-}
-
-bool MinecraftProfile::remove(const QString id)
-{
- int i = 0;
- for (auto patch : m_patches)
- {
- if (patch->getID() == id)
- {
- return remove(i);
- }
- i++;
- }
- return false;
-}
-
-bool MinecraftProfile::customize(int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isCustomizable())
- {
- qDebug() << "Patch" << patch->getID() << "is not customizable";
- return false;
- }
- if(!m_strategy->customizePatch(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be customized";
- return false;
- }
- reapplyPatches();
- saveCurrentOrder();
- // FIXME: maybe later in unstable
- // emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- return true;
-}
-
-bool MinecraftProfile::revertToBase(int index)
-{
- auto patch = versionPatch(index);
- if (!patch->isRevertible())
- {
- qDebug() << "Patch" << patch->getID() << "is not revertible";
- return false;
- }
- if(!m_strategy->revertPatch(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be reverted";
- return false;
- }
- reapplyPatches();
- saveCurrentOrder();
- // FIXME: maybe later in unstable
- // emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- return true;
-}
-
-ProfilePatchPtr MinecraftProfile::versionPatch(const QString &id)
-{
- for (auto file : m_patches)
- {
- if (file->getID() == id)
- {
- return file;
- }
- }
- return nullptr;
-}
-
-ProfilePatchPtr MinecraftProfile::versionPatch(int index)
-{
- if(index < 0 || index >= m_patches.size())
- return nullptr;
- return m_patches[index];
-}
-
-bool MinecraftProfile::isVanilla()
-{
- for(auto patchptr: m_patches)
- {
- if(patchptr->isCustom())
- return false;
- }
- return true;
-}
-
-bool MinecraftProfile::revertToVanilla()
-{
- // remove patches, if present
- auto VersionPatchesCopy = m_patches;
- for(auto & it: VersionPatchesCopy)
- {
- if (!it->isCustom())
- {
- continue;
- }
- if(it->isRevertible() || it->isRemovable())
- {
- if(!remove(it->getID()))
- {
- qWarning() << "Couldn't remove" << it->getID() << "from profile!";
- reapplyPatches();
- saveCurrentOrder();
- return false;
- }
- }
- }
- reapplyPatches();
- saveCurrentOrder();
- return true;
-}
-
-QVariant MinecraftProfile::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= m_patches.size())
- return QVariant();
-
- auto patch = m_patches.at(row);
-
- if (role == Qt::DisplayRole)
- {
- switch (column)
- {
- case 0:
- return m_patches.at(row)->getName();
- case 1:
- {
- if(patch->isCustom())
- {
- return QString("%1 (Custom)").arg(patch->getVersion());
- }
- else
- {
- return patch->getVersion();
- }
- }
- default:
- return QVariant();
- }
- }
- if(role == Qt::DecorationRole)
- {
- switch(column)
- {
- case 0:
- {
- auto severity = patch->getProblemSeverity();
- switch (severity)
- {
- case PROBLEM_WARNING:
- return "warning";
- case PROBLEM_ERROR:
- return "error";
- default:
- return QVariant();
- }
- }
- default:
- {
- return QVariant();
- }
- }
- }
- return QVariant();
-}
-QVariant MinecraftProfile::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal)
- {
- if (role == Qt::DisplayRole)
- {
- switch (section)
- {
- case 0:
- return tr("Name");
- case 1:
- return tr("Version");
- default:
- return QVariant();
- }
- }
- }
- return QVariant();
-}
-Qt::ItemFlags MinecraftProfile::flags(const QModelIndex &index) const
-{
- if (!index.isValid())
- return Qt::NoItemFlags;
- return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-}
-
-int MinecraftProfile::rowCount(const QModelIndex &parent) const
-{
- return m_patches.size();
-}
-
-int MinecraftProfile::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-void MinecraftProfile::saveCurrentOrder() const
-{
- ProfileUtils::PatchOrder order;
- for(auto item: m_patches)
- {
- if(!item->isMoveable())
- continue;
- order.append(item->getID());
- }
- m_strategy->saveOrder(order);
-}
-
-void MinecraftProfile::move(const int index, const MoveDirection direction)
-{
- int theirIndex;
- if (direction == MoveUp)
- {
- theirIndex = index - 1;
- }
- else
- {
- theirIndex = index + 1;
- }
-
- if (index < 0 || index >= m_patches.size())
- return;
- if (theirIndex >= rowCount())
- theirIndex = rowCount() - 1;
- if (theirIndex == -1)
- theirIndex = rowCount() - 1;
- if (index == theirIndex)
- return;
- int togap = theirIndex > index ? theirIndex + 1 : theirIndex;
-
- auto from = versionPatch(index);
- auto to = versionPatch(theirIndex);
-
- if (!from || !to || !to->isMoveable() || !from->isMoveable())
- {
- return;
- }
- beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
- m_patches.swap(index, theirIndex);
- endMoveRows();
- reapplyPatches();
- saveCurrentOrder();
-}
-void MinecraftProfile::resetOrder()
-{
- m_strategy->resetOrder();
- reload();
-}
-
-bool MinecraftProfile::reapplyPatches()
-{
- try
- {
- clear();
- for(auto file: m_patches)
- {
- file->applyTo(this);
- }
- }
- catch (Exception & error)
- {
- clear();
- qWarning() << "Couldn't apply profile patches because: " << error.cause();
- return false;
- }
- return true;
-}
-
-static void applyString(const QString & from, QString & to)
-{
- if(from.isEmpty())
- return;
- to = from;
-}
-
-void MinecraftProfile::applyMinecraftVersion(const QString& id)
-{
- applyString(id, this->m_minecraftVersion);
-}
-
-void MinecraftProfile::applyAppletClass(const QString& appletClass)
-{
- applyString(appletClass, this->m_appletClass);
-}
-
-void MinecraftProfile::applyMainClass(const QString& mainClass)
-{
- applyString(mainClass, this->m_mainClass);
-}
-
-void MinecraftProfile::applyMinecraftArguments(const QString& minecraftArguments)
-{
- applyString(minecraftArguments, this->m_minecraftArguments);
-}
-
-void MinecraftProfile::applyMinecraftVersionType(const QString& type)
-{
- applyString(type, this->m_minecraftVersionType);
-}
-
-void MinecraftProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets)
-{
- if(assets)
- {
- m_minecraftAssets = assets;
- }
-}
-
-void MinecraftProfile::applyMojangDownload(const QString &key, MojangDownloadInfo::Ptr download)
-{
- if(download)
- {
- mojangDownloads[key] = download;
- }
- else
- {
- mojangDownloads.remove(key);
- }
-}
-
-void MinecraftProfile::applyTraits(const QSet<QString>& traits)
-{
- this->m_traits.unite(traits);
-}
-
-void MinecraftProfile::applyTweakers(const QStringList& tweakers)
-{
- // FIXME: check for dupes?
- // FIXME: does order matter?
- for (auto tweaker : tweakers)
- {
- this->m_tweakers += tweaker;
- }
-}
-
-void MinecraftProfile::applyJarMods(const QList<JarmodPtr>& jarMods)
-{
- this->m_jarMods.append(jarMods);
-}
-
-static int findLibraryByName(QList<LibraryPtr> haystack, const GradleSpecifier &needle)
-{
- int retval = -1;
- for (int i = 0; i < haystack.size(); ++i)
- {
- if (haystack.at(i)->rawName().matchName(needle))
- {
- // only one is allowed.
- if (retval != -1)
- return -1;
- retval = i;
- }
- }
- return retval;
-}
-
-void MinecraftProfile::applyLibrary(LibraryPtr library)
-{
- if(!library->isActive())
- {
- return;
- }
- // find the library by name.
- const int index = findLibraryByName(m_libraries, library->rawName());
- // library not found? just add it.
- if (index < 0)
- {
- m_libraries.append(Library::limitedCopy(library));
- return;
- }
- auto existingLibrary = m_libraries.at(index);
- // if we are higher it means we should update
- if (Version(library->version()) > Version(existingLibrary->version()))
- {
- auto libraryCopy = Library::limitedCopy(library);
- m_libraries.replace(index, libraryCopy);
- }
-}
-
-void MinecraftProfile::applyProblemSeverity(ProblemSeverity severity)
-{
- if (m_problemSeverity < severity)
- {
- m_problemSeverity = severity;
- }
-}
-
-
-QString MinecraftProfile::getMinecraftVersion() const
-{
- return m_minecraftVersion;
-}
-
-QString MinecraftProfile::getAppletClass() const
-{
- return m_appletClass;
-}
-
-QString MinecraftProfile::getMainClass() const
-{
- return m_mainClass;
-}
-
-const QSet<QString> &MinecraftProfile::getTraits() const
-{
- return m_traits;
-}
-
-const QStringList & MinecraftProfile::getTweakers() const
-{
- return m_tweakers;
-}
-
-bool MinecraftProfile::hasTrait(const QString& trait) const
-{
- return m_traits.contains(trait);
-}
-
-ProblemSeverity MinecraftProfile::getProblemSeverity() const
-{
- return m_problemSeverity;
-}
-
-QString MinecraftProfile::getMinecraftVersionType() const
-{
- return m_minecraftVersionType;
-}
-
-std::shared_ptr<MojangAssetIndexInfo> MinecraftProfile::getMinecraftAssets() const
-{
- if(!m_minecraftAssets)
- {
- return std::make_shared<MojangAssetIndexInfo>("legacy");
- }
- return m_minecraftAssets;
-}
-
-QString MinecraftProfile::getMinecraftArguments() const
-{
- return m_minecraftArguments;
-}
-
-const QList<JarmodPtr> & MinecraftProfile::getJarMods() const
-{
- return m_jarMods;
-}
-
-const QList<LibraryPtr> & MinecraftProfile::getLibraries() const
-{
- return m_libraries;
-}
-
-QString MinecraftProfile::getMainJarUrl() const
-{
- auto iter = mojangDownloads.find("client");
- if(iter != mojangDownloads.end())
- {
- // current
- return iter.value()->url;
- }
- else
- {
- // legacy fallback
- return URLConstants::getLegacyJarUrl(getMinecraftVersion());
- }
-}
-
-void MinecraftProfile::installJarMods(QStringList selectedFiles)
-{
- m_strategy->installJarMods(selectedFiles);
-}
-
-/*
- * TODO: get rid of this. Get rid of all order numbers.
- */
-int MinecraftProfile::getFreeOrderNumber()
-{
- int largest = 100;
- // yes, I do realize this is dumb. The order thing itself is dumb. and to be removed next.
- for(auto thing: m_patches)
- {
- int order = thing->getOrder();
- if(order > largest)
- largest = order;
- }
- return largest + 1;
-}
diff --git a/libraries/logic/minecraft/MinecraftProfile.h b/libraries/logic/minecraft/MinecraftProfile.h
deleted file mode 100644
index ca9288ad..00000000
--- a/libraries/logic/minecraft/MinecraftProfile.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QAbstractListModel>
-
-#include <QString>
-#include <QList>
-#include <memory>
-
-#include "Library.h"
-#include "VersionFile.h"
-#include "JarMod.h"
-#include "MojangDownloadInfo.h"
-
-#include "multimc_logic_export.h"
-
-class ProfileStrategy;
-class OneSixInstance;
-
-
-class MULTIMC_LOGIC_EXPORT MinecraftProfile : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- explicit MinecraftProfile(ProfileStrategy *strategy);
-
- void setStrategy(ProfileStrategy * strategy);
- ProfileStrategy *strategy();
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- virtual int columnCount(const QModelIndex &parent) const override;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
-
- /// is this version unchanged by the user?
- bool isVanilla();
-
- /// remove any customizations on top of whatever 'vanilla' means
- bool revertToVanilla();
-
- /// install more jar mods
- void installJarMods(QStringList selectedFiles);
-
- /// DEPRECATED, remove ASAP
- int getFreeOrderNumber();
-
- enum MoveDirection { MoveUp, MoveDown };
- /// move patch file # up or down the list
- void move(const int index, const MoveDirection direction);
-
- /// remove patch file # - including files/records
- bool remove(const int index);
-
- /// remove patch file by id - including files/records
- bool remove(const QString id);
-
- bool customize(int index);
-
- bool revertToBase(int index);
-
- void resetOrder();
-
- /// reload all profile patches from storage, clear the profile and apply the patches
- void reload();
-
- /// clear the profile
- void clear();
-
- /// apply the patches. Catches all the errors and returns true/false for success/failure
- bool reapplyPatches();
-
-public: /* application of profile variables from patches */
- void applyMinecraftVersion(const QString& id);
- void applyMainClass(const QString& mainClass);
- void applyAppletClass(const QString& appletClass);
- void applyMinecraftArguments(const QString& minecraftArguments);
- void applyMinecraftVersionType(const QString& type);
- void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
- void applyTraits(const QSet<QString> &traits);
- void applyTweakers(const QStringList &tweakers);
- void applyJarMods(const QList<JarmodPtr> &jarMods);
- void applyLibrary(LibraryPtr library);
- void applyProblemSeverity(ProblemSeverity severity);
- void applyMojangDownload(const QString & key, MojangDownloadInfo::Ptr download);
-
-public: /* getters for profile variables */
- QString getMinecraftVersion() const;
- QString getMainClass() const;
- QString getAppletClass() const;
- QString getMinecraftVersionType() const;
- MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
- QString getMinecraftArguments() const;
- const QSet<QString> & getTraits() const;
- const QStringList & getTweakers() const;
- const QList<JarmodPtr> & getJarMods() const;
- const QList<LibraryPtr> & getLibraries() const;
- QString getMainJarUrl() const;
- bool hasTrait(const QString & trait) const;
- ProblemSeverity getProblemSeverity() const;
-
-public:
- /// get the profile patch by id
- ProfilePatchPtr versionPatch(const QString &id);
-
- /// get the profile patch by index
- ProfilePatchPtr versionPatch(int index);
-
- /// save the current patch order
- void saveCurrentOrder() const;
-
- /// Remove all the patches
- void clearPatches();
-
- /// Add the patch object to the internal list of patches
- void appendPatch(ProfilePatchPtr patch);
-
-private: /* data */
- /// the version of Minecraft - jar to use
- QString m_minecraftVersion;
-
- /// Release type - "release" or "snapshot"
- QString m_minecraftVersionType;
-
- /// Assets type - "legacy" or a version ID
- MojangAssetIndexInfo::Ptr m_minecraftAssets;
-
- // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more.
- QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
-
- /**
- * arguments that should be used for launching minecraft
- *
- * ex: "--username ${auth_player_name} --session ${auth_session}
- * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}"
- */
- QString m_minecraftArguments;
-
- /// A list of all tweaker classes
- QStringList m_tweakers;
-
- /// The main class to load first
- QString m_mainClass;
-
- /// The applet class, for some very old minecraft releases
- QString m_appletClass;
-
- /// the list of libraries
- QList<LibraryPtr> m_libraries;
-
- /// traits, collected from all the version files (version files can only add)
- QSet<QString> m_traits;
-
- /// A list of jar mods. version files can add those.
- QList<JarmodPtr> m_jarMods;
-
- ProblemSeverity m_problemSeverity = PROBLEM_NONE;
-
- /*
- FIXME: add support for those rules here? Looks like a pile of quick hacks to me though.
-
- "rules": [
- {
- "action": "allow"
- },
- {
- "action": "disallow",
- "os": {
- "name": "osx",
- "version": "^10\\.5\\.\\d$"
- }
- }
- ],
- "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX
- 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!"
- }
- */
- // QList<Rule> rules;
-
- /// list of attached profile patches
- QList<ProfilePatchPtr> m_patches;
-
- /// strategy used for profile operations
- ProfileStrategy *m_strategy = nullptr;
-};
diff --git a/libraries/logic/minecraft/MinecraftVersion.cpp b/libraries/logic/minecraft/MinecraftVersion.cpp
deleted file mode 100644
index 1e1d273c..00000000
--- a/libraries/logic/minecraft/MinecraftVersion.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-#include "MinecraftVersion.h"
-#include "MinecraftProfile.h"
-#include "VersionBuildError.h"
-#include "ProfileUtils.h"
-#include "settings/SettingsObject.h"
-#include "minecraft/VersionFilterData.h"
-
-bool MinecraftVersion::usesLegacyLauncher()
-{
- return getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate;
-}
-
-
-QString MinecraftVersion::descriptor()
-{
- return m_version;
-}
-
-QString MinecraftVersion::name()
-{
- return m_version;
-}
-
-QString MinecraftVersion::typeString() const
-{
- if(m_type == "snapshot")
- {
- return QObject::tr("Snapshot");
- }
- else if (m_type == "release")
- {
- return QObject::tr("Regular release");
- }
- else if (m_type == "old_alpha")
- {
- return QObject::tr("Alpha");
- }
- else if (m_type == "old_beta")
- {
- return QObject::tr("Beta");
- }
- else
- {
- return QString();
- }
-}
-
-VersionSource MinecraftVersion::getVersionSource()
-{
- return m_versionSource;
-}
-
-bool MinecraftVersion::hasJarMods()
-{
- return false;
-}
-
-bool MinecraftVersion::isMinecraftVersion()
-{
- return true;
-}
-
-void MinecraftVersion::applyFileTo(MinecraftProfile *profile)
-{
- if(m_versionSource == Local && getVersionFile())
- {
- getVersionFile()->applyTo(profile);
- }
- else
- {
- throw VersionIncomplete(QObject::tr("Can't apply incomplete/builtin Minecraft version %1").arg(m_version));
- }
-}
-
-QString MinecraftVersion::getUrl() const
-{
- // legacy fallback
- if(m_versionFileURL.isEmpty())
- {
- return QString("http://") + URLConstants::AWS_DOWNLOAD_VERSIONS + m_version + "/" + m_version + ".json";
- }
- // current
- return m_versionFileURL;
-}
-
-VersionFilePtr MinecraftVersion::getVersionFile()
-{
- QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_version));
- m_problems.clear();
- if(!versionFile.exists())
- {
- if(m_loadedVersionFile)
- {
- m_loadedVersionFile.reset();
- }
- addProblem(PROBLEM_WARNING, QObject::tr("The patch file doesn't exist locally. It's possible it just needs to be downloaded."));
- }
- else
- {
- try
- {
- if(versionFile.lastModified() != m_loadedVersionFileTimestamp)
- {
- auto loadedVersionFile = ProfileUtils::parseBinaryJsonFile(versionFile);
- loadedVersionFile->name = "Minecraft";
- loadedVersionFile->setCustomizable(true);
- m_loadedVersionFileTimestamp = versionFile.lastModified();
- m_loadedVersionFile = loadedVersionFile;
- }
- }
- catch(Exception e)
- {
- m_loadedVersionFile.reset();
- addProblem(PROBLEM_ERROR, QObject::tr("The patch file couldn't be read:\n%1").arg(e.cause()));
- }
- }
- return m_loadedVersionFile;
-}
-
-bool MinecraftVersion::isCustomizable()
-{
- switch(m_versionSource)
- {
- case Local:
- case Remote:
- // locally cached file, or a remote file that we can acquire can be customized
- return true;
- default:
- // Everything else is undefined and therefore not customizable.
- return false;
- }
- return false;
-}
-
-const QList<PatchProblem> &MinecraftVersion::getProblems()
-{
- if(getVersionFile())
- {
- return getVersionFile()->getProblems();
- }
- return ProfilePatch::getProblems();
-}
-
-ProblemSeverity MinecraftVersion::getProblemSeverity()
-{
- if(getVersionFile())
- {
- return getVersionFile()->getProblemSeverity();
- }
- return ProfilePatch::getProblemSeverity();
-}
-
-void MinecraftVersion::applyTo(MinecraftProfile *profile)
-{
- // do we have this one cached?
- if (m_versionSource == Local)
- {
- applyFileTo(profile);
- return;
- }
- throw VersionIncomplete(QObject::tr("Minecraft version %1 could not be applied: version files are missing.").arg(m_version));
-}
-
-int MinecraftVersion::getOrder()
-{
- return order;
-}
-
-void MinecraftVersion::setOrder(int order)
-{
- this->order = order;
-}
-
-QList<JarmodPtr> MinecraftVersion::getJarMods()
-{
- return QList<JarmodPtr>();
-}
-
-QString MinecraftVersion::getName()
-{
- return "Minecraft";
-}
-QString MinecraftVersion::getVersion()
-{
- return m_version;
-}
-QString MinecraftVersion::getID()
-{
- return "net.minecraft";
-}
-QString MinecraftVersion::getFilename()
-{
- return QString();
-}
-QDateTime MinecraftVersion::getReleaseDateTime()
-{
- return m_releaseTime;
-}
-
-
-bool MinecraftVersion::needsUpdate()
-{
- return m_versionSource == Remote || hasUpdate();
-}
-
-bool MinecraftVersion::hasUpdate()
-{
- return m_versionSource == Remote || (m_versionSource == Local && upstreamUpdate);
-}
-
-bool MinecraftVersion::isCustom()
-{
- // if we add any other source types, this will evaluate to false for them.
- return m_versionSource != Local && m_versionSource != Remote;
-}
diff --git a/libraries/logic/minecraft/MinecraftVersion.h b/libraries/logic/minecraft/MinecraftVersion.h
deleted file mode 100644
index b21427d9..00000000
--- a/libraries/logic/minecraft/MinecraftVersion.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QStringList>
-#include <QSet>
-#include <QDateTime>
-
-#include "BaseVersion.h"
-#include "ProfilePatch.h"
-#include "VersionFile.h"
-
-#include "multimc_logic_export.h"
-
-class MinecraftProfile;
-class MinecraftVersion;
-typedef std::shared_ptr<MinecraftVersion> MinecraftVersionPtr;
-
-class MULTIMC_LOGIC_EXPORT MinecraftVersion : public BaseVersion, public ProfilePatch
-{
-friend class MinecraftVersionList;
-
-public: /* methods */
- // FIXME: nuke this.
- bool usesLegacyLauncher();
-
- virtual QString descriptor() override;
- virtual QString name() override;
- virtual QString typeString() const override;
- virtual bool hasJarMods() override;
- virtual bool isMinecraftVersion() override;
- virtual void applyTo(MinecraftProfile *profile) override;
- virtual int getOrder() override;
- virtual void setOrder(int order) override;
- virtual QList<JarmodPtr> getJarMods() override;
- virtual QString getID() override;
- virtual QString getVersion() override;
- virtual QString getName() override;
- virtual QString getFilename() override;
- QDateTime getReleaseDateTime() override;
- VersionSource getVersionSource() override;
-
- bool needsUpdate();
- bool hasUpdate();
- virtual bool isCustom() override;
- virtual bool isMoveable() override
- {
- return false;
- }
- virtual bool isCustomizable() override;
- virtual bool isRemovable() override
- {
- return false;
- }
- virtual bool isRevertible() override
- {
- return false;
- }
- virtual bool isEditable() override
- {
- return false;
- }
- virtual bool isVersionChangeable() override
- {
- return true;
- }
-
- virtual VersionFilePtr getVersionFile() override;
-
- // virtual QJsonDocument toJson(bool saveOrder) override;
-
- QString getUrl() const;
-
- virtual const QList<PatchProblem> &getProblems() override;
- virtual ProblemSeverity getProblemSeverity() override;
-
-private: /* methods */
- void applyFileTo(MinecraftProfile *profile);
-
-protected: /* data */
- VersionSource m_versionSource = Remote;
-
- /// The URL that this version will be downloaded from.
- QString m_versionFileURL;
-
- /// the human readable version name
- QString m_version;
-
- /// The type of this release
- QString m_type;
-
- /// the time this version was actually released by Mojang
- QDateTime m_releaseTime;
-
- /// the time this version was last updated by Mojang
- QDateTime m_updateTime;
-
- /// order of this file... default = -2
- int order = -2;
-
- /// an update available from Mojang
- MinecraftVersionPtr upstreamUpdate;
-
- QDateTime m_loadedVersionFileTimestamp;
- mutable VersionFilePtr m_loadedVersionFile;
-};
diff --git a/libraries/logic/minecraft/MinecraftVersionList.cpp b/libraries/logic/minecraft/MinecraftVersionList.cpp
deleted file mode 100644
index a5cc3a39..00000000
--- a/libraries/logic/minecraft/MinecraftVersionList.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-/* Copyright 2013-2015 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 <QtXml>
-#include "Json.h"
-#include <QtAlgorithms>
-#include <QtNetwork>
-
-#include "Env.h"
-#include "Exception.h"
-
-#include "MinecraftVersionList.h"
-#include "net/URLConstants.h"
-
-#include "ParseUtils.h"
-#include "ProfileUtils.h"
-#include "VersionFilterData.h"
-#include "onesix/OneSixVersionFormat.h"
-#include "MojangVersionFormat.h"
-#include <FileSystem.h>
-
-static const char * localVersionCache = "versions/versions.dat";
-
-class MCVListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit MCVListLoadTask(MinecraftVersionList *vlist);
- virtual ~MCVListLoadTask() override{};
-
- virtual void executeTask() override;
-
-protected
-slots:
- void list_downloaded();
-
-protected:
- QNetworkReply *vlistReply;
- MinecraftVersionList *m_list;
- MinecraftVersion *m_currentStable;
-};
-
-class MCVListVersionUpdateTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr<MinecraftVersion> updatedVersion);
- virtual ~MCVListVersionUpdateTask() override{};
- virtual void executeTask() override;
-
-protected
-slots:
- void json_downloaded();
-
-protected:
- NetJobPtr specificVersionDownloadJob;
- std::shared_ptr<MinecraftVersion> updatedVersion;
- MinecraftVersionList *m_list;
-};
-
-class ListLoadError : public Exception
-{
-public:
- ListLoadError(QString cause) : Exception(cause) {};
- virtual ~ListLoadError() noexcept
- {
- }
-};
-
-MinecraftVersionList::MinecraftVersionList(QObject *parent) : BaseVersionList(parent)
-{
- loadCachedList();
-}
-
-Task *MinecraftVersionList::getLoadTask()
-{
- return new MCVListLoadTask(this);
-}
-
-bool MinecraftVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr MinecraftVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int MinecraftVersionList::count() const
-{
- return m_vlist.count();
-}
-
-static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
-{
- auto left = std::dynamic_pointer_cast<MinecraftVersion>(first);
- auto right = std::dynamic_pointer_cast<MinecraftVersion>(second);
- return left->getReleaseDateTime() > right->getReleaseDateTime();
-}
-
-void MinecraftVersionList::sortInternal()
-{
- qSort(m_vlist.begin(), m_vlist.end(), cmpVersions);
-}
-
-void MinecraftVersionList::loadCachedList()
-{
- QFile localIndex(localVersionCache);
- if (!localIndex.exists())
- {
- return;
- }
- if (!localIndex.open(QIODevice::ReadOnly))
- {
- // FIXME: this is actually a very bad thing! How do we deal with this?
- qCritical() << "The minecraft version cache can't be read.";
- return;
- }
- auto data = localIndex.readAll();
- try
- {
- localIndex.close();
- QJsonDocument jsonDoc = QJsonDocument::fromBinaryData(data);
- if (jsonDoc.isNull())
- {
- throw ListLoadError(tr("Error reading the version list."));
- }
- loadList(jsonDoc, Local);
- }
- catch (Exception &e)
- {
- // the cache has gone bad for some reason... flush it.
- qCritical() << "The minecraft version cache is corrupted. Flushing cache.";
- localIndex.remove();
- return;
- }
- m_hasLocalIndex = true;
-}
-
-void MinecraftVersionList::loadList(QJsonDocument jsonDoc, VersionSource source)
-{
- qDebug() << "Loading" << ((source == Remote) ? "remote" : "local") << "version list.";
-
- if (!jsonDoc.isObject())
- {
- throw ListLoadError(tr("Error parsing version list JSON: jsonDoc is not an object"));
- }
-
- QJsonObject root = jsonDoc.object();
-
- try
- {
- QJsonObject latest = Json::requireObject(root.value("latest"));
- m_latestReleaseID = Json::requireString(latest.value("release"));
- m_latestSnapshotID = Json::requireString(latest.value("snapshot"));
- }
- catch (Exception &err)
- {
- qCritical()
- << tr("Error parsing version list JSON: couldn't determine latest versions");
- }
-
- // Now, get the array of versions.
- if (!root.value("versions").isArray())
- {
- throw ListLoadError(tr("Error parsing version list JSON: version list object is "
- "missing 'versions' array"));
- }
- QJsonArray versions = root.value("versions").toArray();
-
- QList<BaseVersionPtr> tempList;
- for (auto version : versions)
- {
- // Load the version info.
- if (!version.isObject())
- {
- qCritical() << "Error while parsing version list : invalid JSON structure";
- continue;
- }
-
- QJsonObject versionObj = version.toObject();
- QString versionID = versionObj.value("id").toString("");
- if (versionID.isEmpty())
- {
- qCritical() << "Error while parsing version : version ID is missing";
- continue;
- }
-
- if (g_VersionFilterData.legacyBlacklist.contains(versionID))
- {
- qWarning() << "Blacklisted legacy version ignored: " << versionID;
- continue;
- }
-
- // Now, we construct the version object and add it to the list.
- std::shared_ptr<MinecraftVersion> mcVersion(new MinecraftVersion());
- mcVersion->m_version = versionID;
-
- mcVersion->m_releaseTime = timeFromS3Time(versionObj.value("releaseTime").toString(""));
- mcVersion->m_updateTime = timeFromS3Time(versionObj.value("time").toString(""));
-
- // depends on where we load the version from -- network request or local file?
- mcVersion->m_versionSource = source;
- mcVersion->m_versionFileURL = versionObj.value("url").toString("");
- QString versionTypeStr = versionObj.value("type").toString("");
- if (versionTypeStr.isEmpty())
- {
- qCritical() << "Ignoring" << versionID
- << "because it doesn't have the version type set.";
- continue;
- }
- // OneSix or Legacy. use filter to determine type
- if (versionTypeStr == "release")
- {
- }
- else if (versionTypeStr == "snapshot") // It's a snapshot... yay
- {
- }
- else if (versionTypeStr == "old_alpha")
- {
- }
- else if (versionTypeStr == "old_beta")
- {
- }
- else
- {
- qCritical() << "Ignoring" << versionID
- << "because it has an invalid version type.";
- continue;
- }
- mcVersion->m_type = versionTypeStr;
- qDebug() << "Loaded version" << versionID << "from"
- << ((source == Remote) ? "remote" : "local") << "version list.";
- tempList.append(mcVersion);
- }
- updateListData(tempList);
- if(source == Remote)
- {
- m_loaded = true;
- }
-}
-
-void MinecraftVersionList::sortVersions()
-{
- beginResetModel();
- sortInternal();
- endResetModel();
-}
-
-QVariant MinecraftVersionList::data(const QModelIndex& index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<MinecraftVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case RecommendedRole:
- return version->descriptor() == m_latestReleaseID;
-
- case LatestRole:
- {
- if(version->descriptor() != m_latestSnapshotID)
- return false;
- MinecraftVersionPtr latestRelease = std::dynamic_pointer_cast<MinecraftVersion>(getLatestStable());
- /*
- if(latestRelease && latestRelease->m_releaseTime > version->m_releaseTime)
- {
- return false;
- }
- */
- return true;
- }
-
- case TypeRole:
- return version->typeString();
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList MinecraftVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, RecommendedRole, LatestRole, TypeRole};
-}
-
-BaseVersionPtr MinecraftVersionList::getLatestStable() const
-{
- if(m_lookup.contains(m_latestReleaseID))
- return m_lookup[m_latestReleaseID];
- return BaseVersionPtr();
-}
-
-BaseVersionPtr MinecraftVersionList::getRecommended() const
-{
- return getLatestStable();
-}
-
-void MinecraftVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- for (auto version : versions)
- {
- auto descr = version->descriptor();
-
- if (!m_lookup.contains(descr))
- {
- m_lookup[version->descriptor()] = version;
- m_vlist.append(version);
- continue;
- }
- auto orig = std::dynamic_pointer_cast<MinecraftVersion>(m_lookup[descr]);
- auto added = std::dynamic_pointer_cast<MinecraftVersion>(version);
- // updateListData is called after Mojang list loads. those can be local or remote
- // remote comes always after local
- // any other options are ignored
- if (orig->m_versionSource != Local || added->m_versionSource != Remote)
- {
- continue;
- }
- // alright, it's an update. put it inside the original, for further processing.
- orig->upstreamUpdate = added;
- }
- sortInternal();
- endResetModel();
-}
-
-MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist)
-{
- m_list = vlist;
- m_currentStable = NULL;
- vlistReply = nullptr;
-}
-
-void MCVListLoadTask::executeTask()
-{
- setStatus(tr("Loading instance version list..."));
- auto worker = ENV.qnam();
- vlistReply = worker->get(QNetworkRequest(QUrl("https://launchermeta.mojang.com/mc/game/version_manifest.json")));
- connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded()));
-}
-
-void MCVListLoadTask::list_downloaded()
-{
- if (vlistReply->error() != QNetworkReply::NoError)
- {
- vlistReply->deleteLater();
- emitFailed("Failed to load Minecraft main version list" + vlistReply->errorString());
- return;
- }
-
- auto data = vlistReply->readAll();
- vlistReply->deleteLater();
- try
- {
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- throw ListLoadError(
- tr("Error parsing version list JSON: %1").arg(jsonError.errorString()));
- }
- m_list->loadList(jsonDoc, Remote);
- }
- catch (Exception &e)
- {
- emitFailed(e.cause());
- return;
- }
-
- emitSucceeded();
- return;
-}
-
-MCVListVersionUpdateTask::MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr<MinecraftVersion> updatedVersion)
- : Task()
-{
- m_list = vlist;
- this->updatedVersion = updatedVersion;
-}
-
-void MCVListVersionUpdateTask::executeTask()
-{
- auto job = new NetJob("Version index");
- job->addNetAction(ByteArrayDownload::make(QUrl(updatedVersion->getUrl())));
- specificVersionDownloadJob.reset(job);
- connect(specificVersionDownloadJob.get(), SIGNAL(succeeded()), SLOT(json_downloaded()));
- connect(specificVersionDownloadJob.get(), SIGNAL(failed(QString)), SIGNAL(failed(QString)));
- connect(specificVersionDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- specificVersionDownloadJob->start();
-}
-
-void MCVListVersionUpdateTask::json_downloaded()
-{
- NetActionPtr DlJob = specificVersionDownloadJob->first();
- auto data = std::dynamic_pointer_cast<ByteArrayDownload>(DlJob)->m_data;
- specificVersionDownloadJob.reset();
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed(tr("The download version file is not valid."));
- return;
- }
- VersionFilePtr file;
- try
- {
- file = MojangVersionFormat::versionFileFromJson(jsonDoc, "net.minecraft.json");
- }
- catch (Exception &e)
- {
- emitFailed(tr("Couldn't process version file: %1").arg(e.cause()));
- return;
- }
-
- // Strip LWJGL from the version file. We use our own.
- ProfileUtils::removeLwjglFromPatch(file);
-
- file->fileId = "net.minecraft";
-
- // now dump the file to disk
- auto doc = OneSixVersionFormat::versionFileToJson(file, false);
- auto newdata = doc.toBinaryData();
- auto id = updatedVersion->descriptor();
- QString targetPath = "versions/" + id + "/" + id + ".dat";
- FS::ensureFilePathExists(targetPath);
- QSaveFile vfile1(targetPath);
- if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
- {
- emitFailed(tr("Can't open %1 for writing.").arg(targetPath));
- return;
- }
- qint64 actual = 0;
- if ((actual = vfile1.write(newdata)) != newdata.size())
- {
- emitFailed(tr("Failed to write into %1. Written %2 out of %3.")
- .arg(targetPath)
- .arg(actual)
- .arg(newdata.size()));
- return;
- }
- if (!vfile1.commit())
- {
- emitFailed(tr("Can't commit changes to %1").arg(targetPath));
- return;
- }
-
- m_list->finalizeUpdate(id);
- emitSucceeded();
-}
-
-std::shared_ptr<Task> MinecraftVersionList::createUpdateTask(QString version)
-{
- auto iter = m_lookup.find(version);
- if(iter == m_lookup.end())
- return nullptr;
-
- auto mcversion = std::dynamic_pointer_cast<MinecraftVersion>(*iter);
- if(!mcversion)
- {
- return nullptr;
- }
-
- return std::shared_ptr<Task>(new MCVListVersionUpdateTask(this, mcversion));
-}
-
-void MinecraftVersionList::saveCachedList()
-{
- // FIXME: throw.
- if (!FS::ensureFilePathExists(localVersionCache))
- return;
- QSaveFile tfile(localVersionCache);
- if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
- return;
- QJsonObject toplevel;
- QJsonArray entriesArr;
- for (auto version : m_vlist)
- {
- auto mcversion = std::dynamic_pointer_cast<MinecraftVersion>(version);
- // do not save the remote versions.
- if (mcversion->m_versionSource != Local)
- continue;
- QJsonObject entryObj;
-
- entryObj.insert("id", mcversion->descriptor());
- entryObj.insert("version", mcversion->descriptor());
- entryObj.insert("time", timeToS3Time(mcversion->m_updateTime));
- entryObj.insert("releaseTime", timeToS3Time(mcversion->m_releaseTime));
- entryObj.insert("url", mcversion->m_versionFileURL);
- entryObj.insert("type", mcversion->m_type);
- entriesArr.append(entryObj);
- }
- toplevel.insert("versions", entriesArr);
-
- {
- bool someLatest = false;
- QJsonObject latestObj;
- if(!m_latestReleaseID.isNull())
- {
- latestObj.insert("release", m_latestReleaseID);
- someLatest = true;
- }
- if(!m_latestSnapshotID.isNull())
- {
- latestObj.insert("snapshot", m_latestSnapshotID);
- someLatest = true;
- }
- if(someLatest)
- {
- toplevel.insert("latest", latestObj);
- }
- }
-
- QJsonDocument doc(toplevel);
- QByteArray jsonData = doc.toBinaryData();
- qint64 result = tfile.write(jsonData);
- if (result == -1)
- return;
- if (result != jsonData.size())
- return;
- tfile.commit();
-}
-
-void MinecraftVersionList::finalizeUpdate(QString version)
-{
- int idx = -1;
- for (int i = 0; i < m_vlist.size(); i++)
- {
- if (version == m_vlist[i]->descriptor())
- {
- idx = i;
- break;
- }
- }
- if (idx == -1)
- {
- return;
- }
-
- auto updatedVersion = std::dynamic_pointer_cast<MinecraftVersion>(m_vlist[idx]);
-
- // if we have an update for the version, replace it, make the update local
- if (updatedVersion->upstreamUpdate)
- {
- auto updatedWith = updatedVersion->upstreamUpdate;
- updatedWith->m_versionSource = Local;
- m_vlist[idx] = updatedWith;
- m_lookup[version] = updatedWith;
- }
- else
- {
- // otherwise, just set the version as local;
- updatedVersion->m_versionSource = Local;
- }
-
- dataChanged(index(idx), index(idx));
-
- saveCachedList();
-}
-
-#include "MinecraftVersionList.moc"
diff --git a/libraries/logic/minecraft/MinecraftVersionList.h b/libraries/logic/minecraft/MinecraftVersionList.h
deleted file mode 100644
index 0fca02a7..00000000
--- a/libraries/logic/minecraft/MinecraftVersionList.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QList>
-#include <QSet>
-
-#include "BaseVersionList.h"
-#include "tasks/Task.h"
-#include "minecraft/MinecraftVersion.h"
-#include <net/NetJob.h>
-
-#include "multimc_logic_export.h"
-
-class MCVListLoadTask;
-class MCVListVersionUpdateTask;
-
-class MULTIMC_LOGIC_EXPORT MinecraftVersionList : public BaseVersionList
-{
- Q_OBJECT
-private:
- void sortInternal();
- void loadList(QJsonDocument jsonDoc, VersionSource source);
- void loadCachedList();
- void saveCachedList();
- void finalizeUpdate(QString version);
-public:
- friend class MCVListLoadTask;
- friend class MCVListVersionUpdateTask;
-
- explicit MinecraftVersionList(QObject *parent = 0);
-
- std::shared_ptr<Task> createUpdateTask(QString version);
-
- virtual Task *getLoadTask() override;
- virtual bool isLoaded() override;
- virtual const BaseVersionPtr at(int i) const override;
- virtual int count() const override;
- virtual void sortVersions() override;
- virtual QVariant data(const QModelIndex & index, int role) const override;
- virtual RoleList providesRoles() const override;
-
- virtual BaseVersionPtr getLatestStable() const override;
- virtual BaseVersionPtr getRecommended() const override;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
- QMap<QString, BaseVersionPtr> m_lookup;
-
- bool m_loaded = false;
- bool m_hasLocalIndex = false;
- QString m_latestReleaseID = "INVALID";
- QString m_latestSnapshotID = "INVALID";
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions) override;
-};
diff --git a/libraries/logic/minecraft/Mod.cpp b/libraries/logic/minecraft/Mod.cpp
deleted file mode 100644
index 9b9f76f9..00000000
--- a/libraries/logic/minecraft/Mod.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/* Copyright 2013-2015 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 <QDir>
-#include <QString>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <quazip.h>
-#include <quazipfile.h>
-
-#include "Mod.h"
-#include "settings/INIFile.h"
-#include <FileSystem.h>
-#include <QDebug>
-
-Mod::Mod(const QFileInfo &file)
-{
- repath(file);
-}
-
-void Mod::repath(const QFileInfo &file)
-{
- m_file = file;
- QString name_base = file.fileName();
-
- m_type = Mod::MOD_UNKNOWN;
-
- if (m_file.isDir())
- {
- m_type = MOD_FOLDER;
- m_name = name_base;
- m_mmc_id = name_base;
- }
- else if (m_file.isFile())
- {
- if (name_base.endsWith(".disabled"))
- {
- m_enabled = false;
- name_base.chop(9);
- }
- else
- {
- m_enabled = true;
- }
- m_mmc_id = name_base;
- if (name_base.endsWith(".zip") || name_base.endsWith(".jar"))
- {
- m_type = MOD_ZIPFILE;
- name_base.chop(4);
- }
- else if (name_base.endsWith(".litemod"))
- {
- m_type = MOD_LITEMOD;
- name_base.chop(8);
- }
- else
- {
- m_type = MOD_SINGLEFILE;
- }
- m_name = name_base;
- }
-
- if (m_type == MOD_ZIPFILE)
- {
- QuaZip zip(m_file.filePath());
- if (!zip.open(QuaZip::mdUnzip))
- return;
-
- QuaZipFile file(&zip);
-
- if (zip.setCurrentFile("mcmod.info"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
-
- ReadMCModInfo(file.readAll());
- file.close();
- zip.close();
- return;
- }
- else if (zip.setCurrentFile("forgeversion.properties"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
-
- ReadForgeInfo(file.readAll());
- file.close();
- zip.close();
- return;
- }
-
- zip.close();
- }
- else if (m_type == MOD_FOLDER)
- {
- QFileInfo mcmod_info(FS::PathCombine(m_file.filePath(), "mcmod.info"));
- if (mcmod_info.isFile())
- {
- QFile mcmod(mcmod_info.filePath());
- if (!mcmod.open(QIODevice::ReadOnly))
- return;
- auto data = mcmod.readAll();
- if (data.isEmpty() || data.isNull())
- return;
- ReadMCModInfo(data);
- }
- }
- else if (m_type == MOD_LITEMOD)
- {
- QuaZip zip(m_file.filePath());
- if (!zip.open(QuaZip::mdUnzip))
- return;
-
- QuaZipFile file(&zip);
-
- if (zip.setCurrentFile("litemod.json"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
-
- ReadLiteModInfo(file.readAll());
- file.close();
- }
- zip.close();
- }
-}
-
-// NEW format
-// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/6f62b37cea040daf350dc253eae6326dd9c822c3
-
-// OLD format:
-// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc
-void Mod::ReadMCModInfo(QByteArray contents)
-{
- auto getInfoFromArray = [&](QJsonArray arr)->void
- {
- if (!arr.at(0).isObject())
- return;
- auto firstObj = arr.at(0).toObject();
- m_mod_id = firstObj.value("modid").toString();
- m_name = firstObj.value("name").toString();
- m_version = firstObj.value("version").toString();
- m_homeurl = firstObj.value("url").toString();
- m_updateurl = firstObj.value("updateUrl").toString();
- m_homeurl = m_homeurl.trimmed();
- if(!m_homeurl.isEmpty())
- {
- // fix up url.
- if (!m_homeurl.startsWith("http://") && !m_homeurl.startsWith("https://") &&
- !m_homeurl.startsWith("ftp://"))
- {
- m_homeurl.prepend("http://");
- }
- }
- m_description = firstObj.value("description").toString();
- QJsonArray authors = firstObj.value("authorList").toArray();
- if (authors.size() == 0)
- authors = firstObj.value("authors").toArray();
-
- if (authors.size() == 0)
- m_authors = "";
- else if (authors.size() >= 1)
- {
- m_authors = authors.at(0).toString();
- for (int i = 1; i < authors.size(); i++)
- {
- m_authors += ", " + authors.at(i).toString();
- }
- }
- m_credits = firstObj.value("credits").toString();
- return;
- }
- ;
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
- // this is the very old format that had just the array
- if (jsonDoc.isArray())
- {
- getInfoFromArray(jsonDoc.array());
- }
- else if (jsonDoc.isObject())
- {
- auto val = jsonDoc.object().value("modinfoversion");
- if(val.isUndefined())
- val = jsonDoc.object().value("modListVersion");
- int version = val.toDouble();
- if (version != 2)
- {
- qCritical() << "BAD stuff happened to mod json:";
- qCritical() << contents;
- return;
- }
- auto arrVal = jsonDoc.object().value("modlist");
- if(arrVal.isUndefined())
- arrVal = jsonDoc.object().value("modList");
- if (arrVal.isArray())
- {
- getInfoFromArray(arrVal.toArray());
- }
- }
-}
-
-void Mod::ReadForgeInfo(QByteArray contents)
-{
- // Read the data
- m_name = "Minecraft Forge";
- m_mod_id = "Forge";
- m_homeurl = "http://www.minecraftforge.net/forum/";
- INIFile ini;
- if (!ini.loadFile(contents))
- return;
-
- QString major = ini.get("forge.major.number", "0").toString();
- QString minor = ini.get("forge.minor.number", "0").toString();
- QString revision = ini.get("forge.revision.number", "0").toString();
- QString build = ini.get("forge.build.number", "0").toString();
-
- m_version = major + "." + minor + "." + revision + "." + build;
-}
-
-void Mod::ReadLiteModInfo(QByteArray contents)
-{
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
- auto object = jsonDoc.object();
- if (object.contains("name"))
- {
- m_mod_id = m_name = object.value("name").toString();
- }
- if (object.contains("version"))
- {
- m_version = object.value("version").toString("");
- }
- else
- {
- m_version = object.value("revision").toString("");
- }
- m_mcversion = object.value("mcversion").toString();
- m_authors = object.value("author").toString();
- m_description = object.value("description").toString();
- m_homeurl = object.value("url").toString();
-}
-
-bool Mod::replace(Mod &with)
-{
- if (!destroy())
- return false;
- bool success = false;
- auto t = with.type();
-
- if (t == MOD_ZIPFILE || t == MOD_SINGLEFILE || t == MOD_LITEMOD)
- {
- qDebug() << "Copy: " << with.m_file.filePath() << " to " << m_file.filePath();
- success = QFile::copy(with.m_file.filePath(), m_file.filePath());
- }
- if (t == MOD_FOLDER)
- {
- success = FS::copy(with.m_file.filePath(), m_file.path())();
- }
- if (success)
- {
- m_name = with.m_name;
- m_mmc_id = with.m_mmc_id;
- m_mod_id = with.m_mod_id;
- m_version = with.m_version;
- m_mcversion = with.m_mcversion;
- m_description = with.m_description;
- m_authors = with.m_authors;
- m_credits = with.m_credits;
- m_homeurl = with.m_homeurl;
- m_type = with.m_type;
- m_file.refresh();
- }
- return success;
-}
-
-bool Mod::destroy()
-{
- if (m_type == MOD_FOLDER)
- {
- QDir d(m_file.filePath());
- if (d.removeRecursively())
- {
- m_type = MOD_UNKNOWN;
- return true;
- }
- return false;
- }
- else if (m_type == MOD_SINGLEFILE || m_type == MOD_ZIPFILE || m_type == MOD_LITEMOD)
- {
- QFile f(m_file.filePath());
- if (f.remove())
- {
- m_type = MOD_UNKNOWN;
- return true;
- }
- return false;
- }
- return true;
-}
-
-QString Mod::version() const
-{
- switch (type())
- {
- case MOD_ZIPFILE:
- case MOD_LITEMOD:
- return m_version;
- case MOD_FOLDER:
- return "Folder";
- case MOD_SINGLEFILE:
- return "File";
- default:
- return "VOID";
- }
-}
-
-bool Mod::enable(bool value)
-{
- if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
- return false;
-
- if (m_enabled == value)
- return false;
-
- QString path = m_file.absoluteFilePath();
- if (value)
- {
- QFile foo(path);
- if (!path.endsWith(".disabled"))
- return false;
- path.chop(9);
- if (!foo.rename(path))
- return false;
- }
- else
- {
- QFile foo(path);
- path += ".disabled";
- if (!foo.rename(path))
- return false;
- }
- m_file = QFileInfo(path);
- m_enabled = value;
- return true;
-}
-bool Mod::operator==(const Mod &other) const
-{
- return mmc_id() == other.mmc_id();
-}
-bool Mod::strongCompare(const Mod &other) const
-{
- return mmc_id() == other.mmc_id() && version() == other.version() && type() == other.type();
-}
diff --git a/libraries/logic/minecraft/Mod.h b/libraries/logic/minecraft/Mod.h
deleted file mode 100644
index 19f4c740..00000000
--- a/libraries/logic/minecraft/Mod.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <QFileInfo>
-
-class Mod
-{
-public:
- enum ModType
- {
- MOD_UNKNOWN, //!< Indicates an unspecified mod type.
- MOD_ZIPFILE, //!< The mod is a zip file containing the mod's class files.
- MOD_SINGLEFILE, //!< The mod is a single file (not a zip file).
- MOD_FOLDER, //!< The mod is in a folder on the filesystem.
- MOD_LITEMOD, //!< The mod is a litemod
- };
-
- Mod(const QFileInfo &file);
-
- QFileInfo filename() const
- {
- return m_file;
- }
- QString mmc_id() const
- {
- return m_mmc_id;
- }
- QString mod_id() const
- {
- return m_mod_id;
- }
- ModType type() const
- {
- return m_type;
- }
- QString mcversion() const
- {
- return m_mcversion;
- }
- ;
- bool valid()
- {
- return m_type != MOD_UNKNOWN;
- }
- QString name() const
- {
- if(m_name.trimmed().isEmpty())
- {
- return m_mmc_id;
- }
- return m_name;
- }
-
- QString version() const;
-
- QString homeurl() const
- {
- return m_homeurl;
- }
-
- QString description() const
- {
- return m_description;
- }
-
- QString authors() const
- {
- return m_authors;
- }
-
- QString credits() const
- {
- return m_credits;
- }
-
- bool enabled() const
- {
- return m_enabled;
- }
-
- bool enable(bool value);
-
- // delete all the files of this mod
- bool destroy();
- // replace this mod with a copy of the other
- bool replace(Mod &with);
- // change the mod's filesystem path (used by mod lists for *MAGIC* purposes)
- void repath(const QFileInfo &file);
-
- // WEAK compare operator - used for replacing mods
- bool operator==(const Mod &other) const;
- bool strongCompare(const Mod &other) const;
-
-private:
- void ReadMCModInfo(QByteArray contents);
- void ReadForgeInfo(QByteArray contents);
- void ReadLiteModInfo(QByteArray contents);
-
-protected:
-
- // FIXME: what do do with those? HMM...
- /*
- void ReadModInfoData(QString info);
- void ReadForgeInfoData(QString infoFileData);
- */
-
- QFileInfo m_file;
- QString m_mmc_id;
- QString m_mod_id;
- bool m_enabled = true;
- QString m_name;
- QString m_version;
- QString m_mcversion;
- QString m_homeurl;
- QString m_updateurl;
- QString m_description;
- QString m_authors;
- QString m_credits;
-
- ModType m_type;
-};
diff --git a/libraries/logic/minecraft/ModList.cpp b/libraries/logic/minecraft/ModList.cpp
deleted file mode 100644
index d9ed4886..00000000
--- a/libraries/logic/minecraft/ModList.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/* Copyright 2013-2015 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 "ModList.h"
-#include <FileSystem.h>
-#include <QMimeData>
-#include <QUrl>
-#include <QUuid>
-#include <QString>
-#include <QFileSystemWatcher>
-#include <QDebug>
-
-ModList::ModList(const QString &dir, const QString &list_file)
- : QAbstractListModel(), m_dir(dir), m_list_file(list_file)
-{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_list_id = QUuid::createUuid().toString();
- m_watcher = new QFileSystemWatcher(this);
- is_watching = false;
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
- SLOT(directoryChanged(QString)));
-}
-
-void ModList::startWatching()
-{
- update();
- is_watching = m_watcher->addPath(m_dir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_dir.absolutePath();
- }
-}
-
-void ModList::stopWatching()
-{
- is_watching = !m_watcher->removePath(m_dir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_dir.absolutePath();
- }
-}
-
-void ModList::internalSort(QList<Mod> &what)
-{
- auto predicate = [](const Mod &left, const Mod &right)
- {
- if (left.name() == right.name())
- {
- return left.mmc_id().localeAwareCompare(right.mmc_id()) < 0;
- }
- return left.name().localeAwareCompare(right.name()) < 0;
- };
- std::sort(what.begin(), what.end(), predicate);
-}
-
-bool ModList::update()
-{
- if (!isValid())
- return false;
-
- QList<Mod> orderedMods;
- QList<Mod> newMods;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- bool orderOrStateChanged = false;
-
- // first, process the ordered items (if any)
- OrderList listOrder = readListFile();
- for (auto item : listOrder)
- {
- QFileInfo infoEnabled(m_dir.filePath(item.id));
- QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled"));
- int idxEnabled = folderContents.indexOf(infoEnabled);
- int idxDisabled = folderContents.indexOf(infoDisabled);
- bool isEnabled;
- // if both enabled and disabled versions are present, it's a special case...
- if (idxEnabled >= 0 && idxDisabled >= 0)
- {
- // we only process the one we actually have in the order file.
- // and exactly as we have it.
- // THIS IS A CORNER CASE
- isEnabled = item.enabled;
- }
- else
- {
- // only one is present.
- // we pick the one that we found.
- // we assume the mod was enabled/disabled by external means
- isEnabled = idxEnabled >= 0;
- }
- int idx = isEnabled ? idxEnabled : idxDisabled;
- QFileInfo &info = isEnabled ? infoEnabled : infoDisabled;
- // if the file from the index file exists
- if (idx != -1)
- {
- // remove from the actual folder contents list
- folderContents.takeAt(idx);
- // append the new mod
- orderedMods.append(Mod(info));
- if (isEnabled != item.enabled)
- orderOrStateChanged = true;
- }
- else
- {
- orderOrStateChanged = true;
- }
- }
- // if there are any untracked files...
- if (folderContents.size())
- {
- // the order surely changed!
- for (auto entry : folderContents)
- {
- newMods.append(Mod(entry));
- }
- internalSort(newMods);
- orderedMods.append(newMods);
- orderOrStateChanged = true;
- }
- // otherwise, if we were already tracking some mods
- else if (mods.size())
- {
- // if the number doesn't match, order changed.
- if (mods.size() != orderedMods.size())
- orderOrStateChanged = true;
- // if it does match, compare the mods themselves
- else
- for (int i = 0; i < mods.size(); i++)
- {
- if (!mods[i].strongCompare(orderedMods[i]))
- {
- orderOrStateChanged = true;
- break;
- }
- }
- }
- beginResetModel();
- mods.swap(orderedMods);
- endResetModel();
- if (orderOrStateChanged && !m_list_file.isEmpty())
- {
- qDebug() << "Mod list " << m_list_file << " changed!";
- saveListFile();
- emit changed();
- }
- return true;
-}
-
-void ModList::directoryChanged(QString path)
-{
- update();
-}
-
-ModList::OrderList ModList::readListFile()
-{
- OrderList itemList;
- if (m_list_file.isNull() || m_list_file.isEmpty())
- return itemList;
-
- QFile textFile(m_list_file);
- if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text))
- return OrderList();
-
- QTextStream textStream;
- textStream.setAutoDetectUnicode(true);
- textStream.setDevice(&textFile);
- while (true)
- {
- QString line = textStream.readLine();
- if (line.isNull() || line.isEmpty())
- break;
- else
- {
- OrderItem it;
- it.enabled = !line.endsWith(".disabled");
- if (!it.enabled)
- {
- line.chop(9);
- }
- it.id = line;
- itemList.append(it);
- }
- }
- textFile.close();
- return itemList;
-}
-
-bool ModList::saveListFile()
-{
- if (m_list_file.isNull() || m_list_file.isEmpty())
- return false;
- QFile textFile(m_list_file);
- if (!textFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- return false;
- QTextStream textStream;
- textStream.setGenerateByteOrderMark(true);
- textStream.setCodec("UTF-8");
- textStream.setDevice(&textFile);
- for (auto mod : mods)
- {
- textStream << mod.mmc_id();
- if (!mod.enabled())
- textStream << ".disabled";
- textStream << endl;
- }
- textFile.close();
- return false;
-}
-
-bool ModList::isValid()
-{
- return m_dir.exists() && m_dir.isReadable();
-}
-
-bool ModList::installMod(const QString &filename, int index)
-{
- // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
- QFileInfo fileinfo(FS::NormalizePath(filename));
-
- qDebug() << "installing: " << fileinfo.absoluteFilePath();
-
- if (!fileinfo.exists() || !fileinfo.isReadable() || index < 0)
- {
- return false;
- }
- Mod m(fileinfo);
- if (!m.valid())
- return false;
-
- // if it's already there, replace the original mod (in place)
- int idx = mods.indexOf(m);
- if (idx != -1)
- {
- int idx2 = mods.indexOf(m, idx + 1);
- if (idx2 != -1)
- return false;
- if (mods[idx].replace(m))
- {
-
- auto left = this->index(index);
- auto right = this->index(index, columnCount(QModelIndex()) - 1);
- emit dataChanged(left, right);
- saveListFile();
- update();
- return true;
- }
- return false;
- }
-
- auto type = m.type();
- if (type == Mod::MOD_UNKNOWN)
- return false;
- if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
- {
- QString newpath = FS::PathCombine(m_dir.path(), fileinfo.fileName());
- if (!QFile::copy(fileinfo.filePath(), newpath))
- return false;
- m.repath(newpath);
- beginInsertRows(QModelIndex(), index, index);
- mods.insert(index, m);
- endInsertRows();
- saveListFile();
- update();
- return true;
- }
- else if (type == Mod::MOD_FOLDER)
- {
-
- QString from = fileinfo.filePath();
- QString to = FS::PathCombine(m_dir.path(), fileinfo.fileName());
- if (!FS::copy(from, to)())
- return false;
- m.repath(to);
- beginInsertRows(QModelIndex(), index, index);
- mods.insert(index, m);
- endInsertRows();
- saveListFile();
- update();
- return true;
- }
- return false;
-}
-
-bool ModList::deleteMod(int index)
-{
- if (index >= mods.size() || index < 0)
- return false;
- Mod &m = mods[index];
- if (m.destroy())
- {
- beginRemoveRows(QModelIndex(), index, index);
- mods.removeAt(index);
- endRemoveRows();
- saveListFile();
- emit changed();
- return true;
- }
- return false;
-}
-
-bool ModList::deleteMods(int first, int last)
-{
- for (int i = first; i <= last; i++)
- {
- Mod &m = mods[i];
- m.destroy();
- }
- beginRemoveRows(QModelIndex(), first, last);
- mods.erase(mods.begin() + first, mods.begin() + last + 1);
- endRemoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-bool ModList::moveModTo(int from, int to)
-{
- if (from < 0 || from >= mods.size())
- return false;
- if (to >= rowCount())
- to = rowCount() - 1;
- if (to == -1)
- to = rowCount() - 1;
- if (from == to)
- return false;
- int togap = to > from ? to + 1 : to;
- beginMoveRows(QModelIndex(), from, from, QModelIndex(), togap);
- mods.move(from, to);
- endMoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-bool ModList::moveModUp(int from)
-{
- if (from > 0)
- return moveModTo(from, from - 1);
- return false;
-}
-
-bool ModList::moveModsUp(int first, int last)
-{
- if (first == 0)
- return false;
-
- beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1);
- mods.move(first - 1, last);
- endMoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-bool ModList::moveModDown(int from)
-{
- if (from < 0)
- return false;
- if (from < mods.size() - 1)
- return moveModTo(from, from + 1);
- return false;
-}
-
-bool ModList::moveModsDown(int first, int last)
-{
- if (last == mods.size() - 1)
- return false;
-
- beginMoveRows(QModelIndex(), first, last, QModelIndex(), last + 2);
- mods.move(last + 1, first);
- endMoveRows();
- saveListFile();
- emit changed();
- return true;
-}
-
-int ModList::columnCount(const QModelIndex &parent) const
-{
- return 3;
-}
-
-QVariant ModList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= mods.size())
- return QVariant();
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return mods[row].name();
- case VersionColumn:
- return mods[row].version();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return mods[row].mmc_id();
-
- case Qt::CheckStateRole:
- switch (column)
- {
- case ActiveColumn:
- return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
-}
-
-bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if (role == Qt::CheckStateRole)
- {
- auto &mod = mods[index.row()];
- if (mod.enable(!mod.enabled()))
- {
- emit dataChanged(index, index);
- return true;
- }
- }
- return false;
-}
-
-QVariant ModList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return QString();
- case NameColumn:
- return tr("Name");
- case VersionColumn:
- return tr("Version");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Is the mod enabled?");
- case NameColumn:
- return tr("The name of the mod.");
- case VersionColumn:
- return tr("The version of the mod.");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
-}
-
-Qt::ItemFlags ModList::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
-}
-
-QStringList ModList::mimeTypes() const
-{
- QStringList types;
- types << "text/uri-list";
- types << "text/plain";
- return types;
-}
-
-Qt::DropActions ModList::supportedDropActions() const
-{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
-}
-
-Qt::DropActions ModList::supportedDragActions() const
-{
- // move to other mod lists or VOID
- return Qt::MoveAction;
-}
-
-QMimeData *ModList::mimeData(const QModelIndexList &indexes) const
-{
- QMimeData *data = new QMimeData();
-
- if (indexes.size() == 0)
- return data;
-
- auto idx = indexes[0];
- int row = idx.row();
- if (row < 0 || row >= mods.size())
- return data;
-
- QStringList params;
- params << m_list_id << QString::number(row);
- data->setText(params.join('|'));
- return data;
-}
-
-bool ModList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
-{
- if (action == Qt::IgnoreAction)
- return true;
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- return false;
- if (parent.isValid())
- {
- row = parent.row();
- column = parent.column();
- }
-
- if (row > rowCount())
- row = rowCount();
- if (row == -1)
- row = rowCount();
- if (column == -1)
- column = 0;
- qDebug() << "Drop row: " << row << " column: " << column;
-
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- stopWatching();
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- continue;
- QString filename = url.toLocalFile();
- installMod(filename, row);
- // if there is no ordering, re-sort the list
- if (m_list_file.isEmpty())
- {
- beginResetModel();
- internalSort(mods);
- endResetModel();
- }
- }
- if (was_watching)
- startWatching();
- return true;
- }
- else if (data->hasText())
- {
- QString sourcestr = data->text();
- auto list = sourcestr.split('|');
- if (list.size() != 2)
- return false;
- QString remoteId = list[0];
- int remoteIndex = list[1].toInt();
- qDebug() << "move: " << sourcestr;
- // no moving of things between two lists
- if (remoteId != m_list_id)
- return false;
- // no point moving to the same place...
- if (row == remoteIndex)
- return false;
- // otherwise, move the mod :D
- moveModTo(remoteIndex, row);
- return true;
- }
- return false;
-}
diff --git a/libraries/logic/minecraft/ModList.h b/libraries/logic/minecraft/ModList.h
deleted file mode 100644
index 05ada8ee..00000000
--- a/libraries/logic/minecraft/ModList.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QList>
-#include <QString>
-#include <QDir>
-#include <QAbstractListModel>
-
-#include "minecraft/Mod.h"
-
-#include "multimc_logic_export.h"
-
-class LegacyInstance;
-class BaseInstance;
-class QFileSystemWatcher;
-
-/**
- * A legacy mod list.
- * Backed by a folder.
- */
-class MULTIMC_LOGIC_EXPORT ModList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum Columns
- {
- ActiveColumn = 0,
- NameColumn,
- VersionColumn
- };
- ModList(const QString &dir, const QString &list_file = QString());
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- virtual bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole);
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- return size();
- }
- ;
- virtual QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
- size_t size() const
- {
- return mods.size();
- }
- ;
- bool empty() const
- {
- return size() == 0;
- }
- Mod &operator[](size_t index)
- {
- return mods[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /**
- * Adds the given mod to the list at the given index - if the list supports custom ordering
- */
- virtual bool installMod(const QString & filename, int index = 0);
-
- /// Deletes the mod at the given index.
- virtual bool deleteMod(int index);
-
- /// Deletes all the selected mods
- virtual bool deleteMods(int first, int last);
-
- /**
- * move the mod at index to the position N
- * 0 is the beginning of the list, length() is the end of the list.
- */
- virtual bool moveModTo(int from, int to);
-
- /**
- * move the mod at index one position upwards
- */
- virtual bool moveModUp(int from);
- virtual bool moveModsUp(int first, int last);
-
- /**
- * move the mod at index one position downwards
- */
- virtual bool moveModDown(int from);
- virtual bool moveModsDown(int first, int last);
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- /// get data for drag action
- virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
- /// get the supported mime types
- virtual QStringList mimeTypes() const;
- /// process data from drop action
- virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent);
- /// what drag actions do we support?
- virtual Qt::DropActions supportedDragActions() const;
-
- /// what drop actions do we support?
- virtual Qt::DropActions supportedDropActions() const;
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir()
- {
- return m_dir;
- }
-
- const QList<Mod> & allMods()
- {
- return mods;
- }
-
-private:
- void internalSort(QList<Mod> & what);
- struct OrderItem
- {
- QString id;
- bool enabled = false;
- };
- typedef QList<OrderItem> OrderList;
- OrderList readListFile();
- bool saveListFile();
-private
-slots:
- void directoryChanged(QString path);
-
-signals:
- void changed();
-
-protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching;
- QDir m_dir;
- QString m_list_file;
- QString m_list_id;
- QList<Mod> mods;
-};
diff --git a/libraries/logic/minecraft/MojangDownloadInfo.h b/libraries/logic/minecraft/MojangDownloadInfo.h
deleted file mode 100644
index 1f3306e0..00000000
--- a/libraries/logic/minecraft/MojangDownloadInfo.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#pragma once
-#include <QString>
-#include <QMap>
-#include <memory>
-
-struct MojangDownloadInfo
-{
- // types
- typedef std::shared_ptr<MojangDownloadInfo> Ptr;
-
- // data
- /// Local filesystem path. WARNING: not used, only here so we can pass through mojang files unmolested!
- QString path;
- /// absolute URL of this file
- QString url;
- /// sha-1 checksum of the file
- QString sha1;
- /// size of the file in bytes
- int size;
-};
-
-
-
-struct MojangLibraryDownloadInfo
-{
- MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact): artifact(artifact) {};
- MojangLibraryDownloadInfo() {};
-
- // types
- typedef std::shared_ptr<MojangLibraryDownloadInfo> Ptr;
-
- // methods
- MojangDownloadInfo *getDownloadInfo(QString classifier)
- {
- if (classifier.isNull())
- {
- return artifact.get();
- }
-
- return classifiers[classifier].get();
- }
-
- // data
- MojangDownloadInfo::Ptr artifact;
- QMap<QString, MojangDownloadInfo::Ptr> classifiers;
-};
-
-
-
-struct MojangAssetIndexInfo : public MojangDownloadInfo
-{
- // types
- typedef std::shared_ptr<MojangAssetIndexInfo> Ptr;
-
- // methods
- MojangAssetIndexInfo()
- {
- }
-
- MojangAssetIndexInfo(QString id)
- {
- this->id = id;
- url = "https://s3.amazonaws.com/Minecraft.Download/indexes/" + id + ".json";
- known = false;
- }
-
- // data
- int totalSize;
- QString id;
- bool known = true;
-};
diff --git a/libraries/logic/minecraft/MojangVersionFormat.cpp b/libraries/logic/minecraft/MojangVersionFormat.cpp
deleted file mode 100644
index 34129c9e..00000000
--- a/libraries/logic/minecraft/MojangVersionFormat.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-#include "MojangVersionFormat.h"
-#include "onesix/OneSixVersionFormat.h"
-#include "MinecraftVersion.h"
-#include "VersionBuildError.h"
-#include "MojangDownloadInfo.h"
-
-#include "Json.h"
-using namespace Json;
-#include "ParseUtils.h"
-
-static const int CURRENT_MINIMUM_LAUNCHER_VERSION = 18;
-
-static MojangAssetIndexInfo::Ptr assetIndexFromJson (const QJsonObject &obj);
-static MojangDownloadInfo::Ptr downloadInfoFromJson (const QJsonObject &obj);
-static MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson (const QJsonObject &libObj);
-static QJsonObject assetIndexToJson (MojangAssetIndexInfo::Ptr assetidxinfo);
-static QJsonObject libDownloadInfoToJson (MojangLibraryDownloadInfo::Ptr libinfo);
-static QJsonObject downloadInfoToJson (MojangDownloadInfo::Ptr info);
-
-namespace Bits
-{
-static void readString(const QJsonObject &root, const QString &key, QString &variable)
-{
- if (root.contains(key))
- {
- variable = requireString(root.value(key));
- }
-}
-
-static void readDownloadInfo(MojangDownloadInfo::Ptr out, const QJsonObject &obj)
-{
- // optional, not used
- readString(obj, "path", out->path);
- // required!
- out->sha1 = requireString(obj, "sha1");
- out->url = requireString(obj, "url");
- out->size = requireInteger(obj, "size");
-}
-
-static void readAssetIndex(MojangAssetIndexInfo::Ptr out, const QJsonObject &obj)
-{
- out->totalSize = requireInteger(obj, "totalSize");
- out->id = requireString(obj, "id");
- // out->known = true;
-}
-}
-
-MojangDownloadInfo::Ptr downloadInfoFromJson(const QJsonObject &obj)
-{
- auto out = std::make_shared<MojangDownloadInfo>();
- Bits::readDownloadInfo(out, obj);
- return out;
-}
-
-MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject &obj)
-{
- auto out = std::make_shared<MojangAssetIndexInfo>();
- Bits::readDownloadInfo(out, obj);
- Bits::readAssetIndex(out, obj);
- return out;
-}
-
-QJsonObject downloadInfoToJson(MojangDownloadInfo::Ptr info)
-{
- QJsonObject out;
- if(!info->path.isNull())
- {
- out.insert("path", info->path);
- }
- out.insert("sha1", info->sha1);
- out.insert("size", info->size);
- out.insert("url", info->url);
- return out;
-}
-
-MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject &libObj)
-{
- auto out = std::make_shared<MojangLibraryDownloadInfo>();
- auto dlObj = requireObject(libObj.value("downloads"));
- if(dlObj.contains("artifact"))
- {
- out->artifact = downloadInfoFromJson(requireObject(dlObj, "artifact"));
- }
- if(dlObj.contains("classifiers"))
- {
- auto classifiersObj = requireObject(dlObj, "classifiers");
- for(auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++)
- {
- auto classifier = iter.key();
- auto classifierObj = requireObject(iter.value());
- out->classifiers[classifier] = downloadInfoFromJson(classifierObj);
- }
- }
- return out;
-}
-
-QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo)
-{
- QJsonObject out;
- if(libinfo->artifact)
- {
- out.insert("artifact", downloadInfoToJson(libinfo->artifact));
- }
- if(libinfo->classifiers.size())
- {
- QJsonObject classifiersOut;
- for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++)
- {
- classifiersOut.insert(iter.key(), downloadInfoToJson(iter.value()));
- }
- out.insert("classifiers", classifiersOut);
- }
- return out;
-}
-
-QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr info)
-{
- QJsonObject out;
- if(!info->path.isNull())
- {
- out.insert("path", info->path);
- }
- out.insert("sha1", info->sha1);
- out.insert("size", info->size);
- out.insert("url", info->url);
- out.insert("totalSize", info->totalSize);
- out.insert("id", info->id);
- return out;
-}
-
-void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFile *out)
-{
- Bits::readString(in, "id", out->minecraftVersion);
- Bits::readString(in, "mainClass", out->mainClass);
- Bits::readString(in, "minecraftArguments", out->minecraftArguments);
- if(out->minecraftArguments.isEmpty())
- {
- QString processArguments;
- Bits::readString(in, "processArguments", processArguments);
- QString toCompare = processArguments.toLower();
- if (toCompare == "legacy")
- {
- out->minecraftArguments = " ${auth_player_name} ${auth_session}";
- }
- else if (toCompare == "username_session")
- {
- out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}";
- }
- else if (toCompare == "username_session_version")
- {
- out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}";
- }
- else if (!toCompare.isEmpty())
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments));
- }
- }
- Bits::readString(in, "type", out->type);
-
- Bits::readString(in, "assets", out->assets);
- if(in.contains("assetIndex"))
- {
- out->mojangAssetIndex = assetIndexFromJson(requireObject(in, "assetIndex"));
- }
- else if (!out->assets.isNull())
- {
- out->mojangAssetIndex = std::make_shared<MojangAssetIndexInfo>(out->assets);
- }
-
- out->m_releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
- out->m_updateTime = timeFromS3Time(in.value("time").toString(""));
-
- if (in.contains("minimumLauncherVersion"))
- {
- out->minimumLauncherVersion = requireInteger(in.value("minimumLauncherVersion"));
- if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION)
- {
- out->addProblem(
- PROBLEM_WARNING,
- QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!")
- .arg(out->minimumLauncherVersion)
- .arg(CURRENT_MINIMUM_LAUNCHER_VERSION));
- }
- }
- if(in.contains("downloads"))
- {
- auto downloadsObj = requireObject(in, "downloads");
- for(auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++)
- {
- auto classifier = iter.key();
- auto classifierObj = requireObject(iter.value());
- out->mojangDownloads[classifier] = downloadInfoFromJson(classifierObj);
- }
- }
-}
-
-VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename)
-{
- VersionFilePtr out(new VersionFile());
- if (doc.isEmpty() || doc.isNull())
- {
- throw JSONValidationError(filename + " is empty or null");
- }
- if (!doc.isObject())
- {
- throw JSONValidationError(filename + " is not an object");
- }
-
- QJsonObject root = doc.object();
-
- readVersionProperties(root, out.get());
-
- out->name = "Minecraft";
- out->fileId = "net.minecraft";
- out->version = out->minecraftVersion;
- out->filename = filename;
-
-
- if (root.contains("libraries"))
- {
- for (auto libVal : requireArray(root.value("libraries")))
- {
- auto libObj = requireObject(libVal);
-
- auto lib = MojangVersionFormat::libraryFromJson(libObj, filename);
- out->libraries.append(lib);
- }
- }
- return out;
-}
-
-void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObject& out)
-{
- writeString(out, "id", in->minecraftVersion);
- writeString(out, "mainClass", in->mainClass);
- writeString(out, "minecraftArguments", in->minecraftArguments);
- writeString(out, "type", in->type);
- if(!in->m_releaseTime.isNull())
- {
- writeString(out, "releaseTime", timeToS3Time(in->m_releaseTime));
- }
- if(!in->m_updateTime.isNull())
- {
- writeString(out, "time", timeToS3Time(in->m_updateTime));
- }
- if(in->minimumLauncherVersion != -1)
- {
- out.insert("minimumLauncherVersion", in->minimumLauncherVersion);
- }
- writeString(out, "assets", in->assets);
- if(in->mojangAssetIndex && in->mojangAssetIndex->known)
- {
- out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
- }
- if(in->mojangDownloads.size())
- {
- QJsonObject downloadsOut;
- for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++)
- {
- downloadsOut.insert(iter.key(), downloadInfoToJson(iter.value()));
- }
- out.insert("downloads", downloadsOut);
- }
-}
-
-QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch)
-{
- QJsonObject root;
- writeVersionProperties(patch.get(), root);
- if (!patch->libraries.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->libraries)
- {
- array.append(MojangVersionFormat::libraryToJson(value.get()));
- }
- root.insert("libraries", array);
- }
-
- // write the contents to a json document.
- {
- QJsonDocument out;
- out.setObject(root);
- return out;
- }
-}
-
-LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename)
-{
- LibraryPtr out(new Library());
- if (!libObj.contains("name"))
- {
- throw JSONValidationError(filename + "contains a library that doesn't have a 'name' field");
- }
- out->m_name = libObj.value("name").toString();
-
- Bits::readString(libObj, "url", out->m_repositoryURL);
- if (libObj.contains("extract"))
- {
- out->m_hasExcludes = true;
- auto extractObj = requireObject(libObj.value("extract"));
- for (auto excludeVal : requireArray(extractObj.value("exclude")))
- {
- out->m_extractExcludes.append(requireString(excludeVal));
- }
- }
- if (libObj.contains("natives"))
- {
- QJsonObject nativesObj = requireObject(libObj.value("natives"));
- for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it)
- {
- if (!it.value().isString())
- {
- qWarning() << filename << "contains an invalid native (skipping)";
- }
- OpSys opSys = OpSys_fromString(it.key());
- if (opSys != Os_Other)
- {
- out->m_nativeClassifiers[opSys] = it.value().toString();
- }
- }
- }
- if (libObj.contains("rules"))
- {
- out->applyRules = true;
- out->m_rules = rulesFromJsonV4(libObj);
- }
- if (libObj.contains("downloads"))
- {
- out->m_mojangDownloads = libDownloadInfoFromJson(libObj);
- }
- return out;
-}
-
-QJsonObject MojangVersionFormat::libraryToJson(Library *library)
-{
- QJsonObject libRoot;
- libRoot.insert("name", (QString)library->m_name);
- if (!library->m_repositoryURL.isEmpty())
- {
- libRoot.insert("url", library->m_repositoryURL);
- }
- if (library->isNative())
- {
- QJsonObject nativeList;
- auto iter = library->m_nativeClassifiers.begin();
- while (iter != library->m_nativeClassifiers.end())
- {
- nativeList.insert(OpSys_toString(iter.key()), iter.value());
- iter++;
- }
- libRoot.insert("natives", nativeList);
- if (library->m_extractExcludes.size())
- {
- QJsonArray excludes;
- QJsonObject extract;
- for (auto exclude : library->m_extractExcludes)
- {
- excludes.append(exclude);
- }
- extract.insert("exclude", excludes);
- libRoot.insert("extract", extract);
- }
- }
- if (library->m_rules.size())
- {
- QJsonArray allRules;
- for (auto &rule : library->m_rules)
- {
- QJsonObject ruleObj = rule->toJson();
- allRules.append(ruleObj);
- }
- libRoot.insert("rules", allRules);
- }
- if(library->m_mojangDownloads)
- {
- auto downloadsObj = libDownloadInfoToJson(library->m_mojangDownloads);
- libRoot.insert("downloads", downloadsObj);
- }
- return libRoot;
-}
diff --git a/libraries/logic/minecraft/MojangVersionFormat.h b/libraries/logic/minecraft/MojangVersionFormat.h
deleted file mode 100644
index 4e141088..00000000
--- a/libraries/logic/minecraft/MojangVersionFormat.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <minecraft/VersionFile.h>
-#include <minecraft/Library.h>
-#include <QJsonDocument>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT MojangVersionFormat
-{
-friend class OneSixVersionFormat;
-protected:
- // does not include libraries
- static void readVersionProperties(const QJsonObject& in, VersionFile* out);
- // does not include libraries
- static void writeVersionProperties(const VersionFile* in, QJsonObject& out);
-public:
- // version files / profile patches
- static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename);
- static QJsonDocument versionFileToJson(const VersionFilePtr &patch);
-
- // libraries
- static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject libraryToJson(Library *library);
-};
diff --git a/libraries/logic/minecraft/OpSys.cpp b/libraries/logic/minecraft/OpSys.cpp
deleted file mode 100644
index 4c2a236d..00000000
--- a/libraries/logic/minecraft/OpSys.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2013-2015 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 "OpSys.h"
-
-OpSys OpSys_fromString(QString name)
-{
- if (name == "linux")
- return Os_Linux;
- if (name == "windows")
- return Os_Windows;
- if (name == "osx")
- return Os_OSX;
- return Os_Other;
-}
-
-QString OpSys_toString(OpSys name)
-{
- switch (name)
- {
- case Os_Linux:
- return "linux";
- case Os_OSX:
- return "osx";
- case Os_Windows:
- return "windows";
- default:
- return "other";
- }
-} \ No newline at end of file
diff --git a/libraries/logic/minecraft/OpSys.h b/libraries/logic/minecraft/OpSys.h
deleted file mode 100644
index 9ebea3de..00000000
--- a/libraries/logic/minecraft/OpSys.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <QString>
-enum OpSys
-{
- Os_Windows,
- Os_Linux,
- Os_OSX,
- Os_Other
-};
-
-OpSys OpSys_fromString(QString);
-QString OpSys_toString(OpSys);
-
-#ifdef Q_OS_WIN32
-#define currentSystem Os_Windows
-#else
-#ifdef Q_OS_MAC
-#define currentSystem Os_OSX
-#else
-#define currentSystem Os_Linux
-#endif
-#endif \ No newline at end of file
diff --git a/libraries/logic/minecraft/ParseUtils.cpp b/libraries/logic/minecraft/ParseUtils.cpp
deleted file mode 100644
index ca188432..00000000
--- a/libraries/logic/minecraft/ParseUtils.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <QDateTime>
-#include <QString>
-#include "ParseUtils.h"
-#include <QDebug>
-#include <cstdlib>
-
-QDateTime timeFromS3Time(QString str)
-{
- return QDateTime::fromString(str, Qt::ISODate);
-}
-
-QString timeToS3Time(QDateTime time)
-{
- // this all because Qt can't format timestamps right.
- int offsetRaw = time.offsetFromUtc();
- bool negative = offsetRaw < 0;
- int offsetAbs = std::abs(offsetRaw);
-
- int offsetSeconds = offsetAbs % 60;
- offsetAbs -= offsetSeconds;
-
- int offsetMinutes = offsetAbs % 3600;
- offsetAbs -= offsetMinutes;
- offsetMinutes /= 60;
-
- int offsetHours = offsetAbs / 3600;
-
- QString raw = time.toString("yyyy-MM-ddTHH:mm:ss");
- raw += (negative ? QChar('-') : QChar('+'));
- raw += QString("%1").arg(offsetHours, 2, 10, QChar('0'));
- raw += ":";
- raw += QString("%1").arg(offsetMinutes, 2, 10, QChar('0'));
- return raw;
-}
diff --git a/libraries/logic/minecraft/ParseUtils.h b/libraries/logic/minecraft/ParseUtils.h
deleted file mode 100644
index 2b367a10..00000000
--- a/libraries/logic/minecraft/ParseUtils.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-#include <QString>
-#include <QDateTime>
-
-#include "multimc_logic_export.h"
-
-/// take the timestamp used by S3 and turn it into QDateTime
-MULTIMC_LOGIC_EXPORT QDateTime timeFromS3Time(QString str);
-
-/// take a timestamp and convert it into an S3 timestamp
-MULTIMC_LOGIC_EXPORT QString timeToS3Time(QDateTime);
diff --git a/libraries/logic/minecraft/ProfilePatch.h b/libraries/logic/minecraft/ProfilePatch.h
deleted file mode 100644
index f0c65360..00000000
--- a/libraries/logic/minecraft/ProfilePatch.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-
-#include <memory>
-#include <QList>
-#include <QJsonDocument>
-#include <QDateTime>
-#include "JarMod.h"
-
-class MinecraftProfile;
-
-enum ProblemSeverity
-{
- PROBLEM_NONE,
- PROBLEM_WARNING,
- PROBLEM_ERROR
-};
-
-/// where is a version from?
-enum VersionSource
-{
- Local, //!< version loaded from a file in the cache.
- Remote, //!< incomplete version on a remote server.
-};
-
-class PatchProblem
-{
-public:
- PatchProblem(ProblemSeverity severity, const QString & description)
- {
- m_severity = severity;
- m_description = description;
- }
- const QString & getDescription() const
- {
- return m_description;
- }
- const ProblemSeverity getSeverity() const
- {
- return m_severity;
- }
-private:
- ProblemSeverity m_severity;
- QString m_description;
-};
-
-class ProfilePatch : public std::enable_shared_from_this<ProfilePatch>
-{
-public:
- virtual ~ProfilePatch(){};
- virtual void applyTo(MinecraftProfile *profile) = 0;
-
- virtual bool isMinecraftVersion() = 0;
- virtual bool hasJarMods() = 0;
- virtual QList<JarmodPtr> getJarMods() = 0;
-
- virtual bool isMoveable() = 0;
- virtual bool isCustomizable() = 0;
- virtual bool isRevertible() = 0;
- virtual bool isRemovable() = 0;
- virtual bool isCustom() = 0;
- virtual bool isEditable() = 0;
- virtual bool isVersionChangeable() = 0;
-
- virtual void setOrder(int order) = 0;
- virtual int getOrder() = 0;
-
- virtual QString getID() = 0;
- virtual QString getName() = 0;
- virtual QString getVersion() = 0;
- virtual QDateTime getReleaseDateTime() = 0;
-
- virtual QString getFilename() = 0;
-
- virtual VersionSource getVersionSource() = 0;
-
- virtual std::shared_ptr<class VersionFile> getVersionFile() = 0;
-
- virtual const QList<PatchProblem>& getProblems()
- {
- return m_problems;
- }
- virtual void addProblem(ProblemSeverity severity, const QString &description)
- {
- if(severity > m_problemSeverity)
- {
- m_problemSeverity = severity;
- }
- m_problems.append(PatchProblem(severity, description));
- }
- virtual ProblemSeverity getProblemSeverity()
- {
- return m_problemSeverity;
- }
- virtual bool hasFailed()
- {
- return getProblemSeverity() == PROBLEM_ERROR;
- }
-
-protected:
- QList<PatchProblem> m_problems;
- ProblemSeverity m_problemSeverity = PROBLEM_NONE;
-};
-
-typedef std::shared_ptr<ProfilePatch> ProfilePatchPtr;
diff --git a/libraries/logic/minecraft/ProfileStrategy.h b/libraries/logic/minecraft/ProfileStrategy.h
deleted file mode 100644
index b4dfc4b3..00000000
--- a/libraries/logic/minecraft/ProfileStrategy.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "ProfileUtils.h"
-
-class MinecraftProfile;
-
-class ProfileStrategy
-{
- friend class MinecraftProfile;
-public:
- virtual ~ProfileStrategy(){};
-
- /// load the patch files into the profile
- virtual void load() = 0;
-
- /// reset the order of patches
- virtual bool resetOrder() = 0;
-
- /// save the order of patches, given the order
- virtual bool saveOrder(ProfileUtils::PatchOrder order) = 0;
-
- /// install a list of jar mods into the instance
- virtual bool installJarMods(QStringList filepaths) = 0;
-
- /// remove any files or records that constitute the version patch
- virtual bool removePatch(ProfilePatchPtr jarMod) = 0;
-
- /// make the patch custom, if possible
- virtual bool customizePatch(ProfilePatchPtr patch) = 0;
-
- /// revert the custom patch to 'vanilla', if possible
- virtual bool revertPatch(ProfilePatchPtr patch) = 0;
-protected:
- MinecraftProfile *profile;
-};
diff --git a/libraries/logic/minecraft/ProfileUtils.cpp b/libraries/logic/minecraft/ProfileUtils.cpp
deleted file mode 100644
index ef9b3b28..00000000
--- a/libraries/logic/minecraft/ProfileUtils.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-#include "ProfileUtils.h"
-#include "minecraft/VersionFilterData.h"
-#include "minecraft/onesix/OneSixVersionFormat.h"
-#include "Json.h"
-#include <QDebug>
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QRegularExpression>
-#include <QSaveFile>
-
-namespace ProfileUtils
-{
-
-static const int currentOrderFileVersion = 1;
-
-bool writeOverrideOrders(QString path, const PatchOrder &order)
-{
- QJsonObject obj;
- obj.insert("version", currentOrderFileVersion);
- QJsonArray orderArray;
- for(auto str: order)
- {
- orderArray.append(str);
- }
- obj.insert("order", orderArray);
- QSaveFile orderFile(path);
- if (!orderFile.open(QFile::WriteOnly))
- {
- qCritical() << "Couldn't open" << orderFile.fileName()
- << "for writing:" << orderFile.errorString();
- return false;
- }
- auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
- if(orderFile.write(data) != data.size())
- {
- qCritical() << "Couldn't write all the data into" << orderFile.fileName()
- << "because:" << orderFile.errorString();
- return false;
- }
- if(!orderFile.commit())
- {
- qCritical() << "Couldn't save" << orderFile.fileName()
- << "because:" << orderFile.errorString();
- }
- return true;
-}
-
-bool readOverrideOrders(QString path, PatchOrder &order)
-{
- QFile orderFile(path);
- if (!orderFile.exists())
- {
- qWarning() << "Order file doesn't exist. Ignoring.";
- return false;
- }
- if (!orderFile.open(QFile::ReadOnly))
- {
- qCritical() << "Couldn't open" << orderFile.fileName()
- << " for reading:" << orderFile.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
-
- // and it's valid JSON
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error);
- if (error.error != QJsonParseError::NoError)
- {
- qCritical() << "Couldn't parse" << orderFile.fileName() << ":" << error.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
-
- // and then read it and process it if all above is true.
- try
- {
- auto obj = Json::requireObject(doc);
- // check order file version.
- auto version = Json::requireInteger(obj.value("version"));
- if (version != currentOrderFileVersion)
- {
- throw JSONValidationError(QObject::tr("Invalid order file version, expected %1")
- .arg(currentOrderFileVersion));
- }
- auto orderArray = Json::requireArray(obj.value("order"));
- for(auto item: orderArray)
- {
- order.append(Json::requireString(item));
- }
- }
- catch (JSONValidationError &err)
- {
- qCritical() << "Couldn't parse" << orderFile.fileName() << ": bad file format";
- qWarning() << "Ignoring overriden order";
- order.clear();
- return false;
- }
- return true;
-}
-
-static VersionFilePtr createErrorVersionFile(QString fileId, QString filepath, QString error)
-{
- auto outError = std::make_shared<VersionFile>();
- outError->fileId = outError->name = fileId;
- outError->filename = filepath;
- outError->addProblem(PROBLEM_ERROR, error);
- return outError;
-}
-
-static VersionFilePtr guardedParseJson(const QJsonDocument & doc,const QString &fileId,const QString &filepath,const bool &requireOrder)
-{
- try
- {
- return OneSixVersionFormat::versionFileFromJson(doc, filepath, requireOrder);
- }
- catch (Exception & e)
- {
- return createErrorVersionFile(fileId, filepath, e.cause());
- }
-}
-
-VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder)
-{
- QFile file(fileInfo.absoluteFilePath());
- if (!file.open(QFile::ReadOnly))
- {
- auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- QJsonParseError error;
- auto data = file.readAll();
- QJsonDocument doc = QJsonDocument::fromJson(data, &error);
- file.close();
- if (error.error != QJsonParseError::NoError)
- {
- int line = 1;
- int column = 0;
- for(int i = 0; i < error.offset; i++)
- {
- if(data[i] == '\n')
- {
- line++;
- column = 0;
- continue;
- }
- column++;
- }
- auto errorStr = QObject::tr("Unable to process the version file %1: %2 at line %3 column %4.")
- .arg(fileInfo.fileName(), error.errorString())
- .arg(line).arg(column);
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), requireOrder);
-}
-
-VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo)
-{
- QFile file(fileInfo.absoluteFilePath());
- if (!file.open(QFile::ReadOnly))
- {
- auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- QJsonDocument doc = QJsonDocument::fromBinaryData(file.readAll());
- file.close();
- if (doc.isNull())
- {
- file.remove();
- throw JSONValidationError(QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName()));
- }
- return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), false);
-}
-
-void removeLwjglFromPatch(VersionFilePtr patch)
-{
- auto filter = [](QList<LibraryPtr>& libs)
- {
- QList<LibraryPtr> filteredLibs;
- for (auto lib : libs)
- {
- if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix()))
- {
- filteredLibs.append(lib);
- }
- }
- libs = filteredLibs;
- };
- filter(patch->libraries);
-}
-}
diff --git a/libraries/logic/minecraft/ProfileUtils.h b/libraries/logic/minecraft/ProfileUtils.h
deleted file mode 100644
index 267fd42b..00000000
--- a/libraries/logic/minecraft/ProfileUtils.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-#include "Library.h"
-#include "VersionFile.h"
-
-namespace ProfileUtils
-{
-typedef QStringList PatchOrder;
-
-/// Read and parse a OneSix format order file
-bool readOverrideOrders(QString path, PatchOrder &order);
-
-/// Write a OneSix format order file
-bool writeOverrideOrders(QString path, const PatchOrder &order);
-
-
-/// Parse a version file in JSON format
-VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder);
-
-/// Parse a version file in binary JSON format
-VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo);
-
-/// Remove LWJGL from a patch file. This is applied to all Mojang-like profile files.
-void removeLwjglFromPatch(VersionFilePtr patch);
-
-}
diff --git a/libraries/logic/minecraft/Rule.cpp b/libraries/logic/minecraft/Rule.cpp
deleted file mode 100644
index c8ba297b..00000000
--- a/libraries/logic/minecraft/Rule.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright 2013-2015 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 <QJsonObject>
-#include <QJsonArray>
-
-#include "Rule.h"
-
-RuleAction RuleAction_fromString(QString name)
-{
- if (name == "allow")
- return Allow;
- if (name == "disallow")
- return Disallow;
- return Defer;
-}
-
-QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules)
-{
- QList<std::shared_ptr<Rule>> rules;
- auto rulesVal = objectWithRules.value("rules");
- if (!rulesVal.isArray())
- return rules;
-
- QJsonArray ruleList = rulesVal.toArray();
- for (auto ruleVal : ruleList)
- {
- std::shared_ptr<Rule> rule;
- if (!ruleVal.isObject())
- continue;
- auto ruleObj = ruleVal.toObject();
- auto actionVal = ruleObj.value("action");
- if (!actionVal.isString())
- continue;
- auto action = RuleAction_fromString(actionVal.toString());
- if (action == Defer)
- continue;
-
- auto osVal = ruleObj.value("os");
- if (!osVal.isObject())
- {
- // add a new implicit action rule
- rules.append(ImplicitRule::create(action));
- continue;
- }
-
- auto osObj = osVal.toObject();
- auto osNameVal = osObj.value("name");
- if (!osNameVal.isString())
- continue;
- OpSys requiredOs = OpSys_fromString(osNameVal.toString());
- QString versionRegex = osObj.value("version").toString();
- // add a new OS rule
- rules.append(OsRule::create(action, requiredOs, versionRegex));
- }
- return rules;
-}
-
-QJsonObject ImplicitRule::toJson()
-{
- QJsonObject ruleObj;
- ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
- return ruleObj;
-}
-
-QJsonObject OsRule::toJson()
-{
- QJsonObject ruleObj;
- ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
- QJsonObject osObj;
- {
- osObj.insert("name", OpSys_toString(m_system));
- if(!m_version_regexp.isEmpty())
- {
- osObj.insert("version", m_version_regexp);
- }
- }
- ruleObj.insert("os", osObj);
- return ruleObj;
-}
-
diff --git a/libraries/logic/minecraft/Rule.h b/libraries/logic/minecraft/Rule.h
deleted file mode 100644
index c8bf6eaa..00000000
--- a/libraries/logic/minecraft/Rule.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-#include <QList>
-#include <QJsonObject>
-#include <memory>
-#include "OpSys.h"
-
-class Library;
-class Rule;
-
-enum RuleAction
-{
- Allow,
- Disallow,
- Defer
-};
-
-QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules);
-
-class Rule
-{
-protected:
- RuleAction m_result;
- virtual bool applies(const Library *parent) = 0;
-
-public:
- Rule(RuleAction result) : m_result(result)
- {
- }
- virtual ~Rule() {};
- virtual QJsonObject toJson() = 0;
- RuleAction apply(const Library *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(const Library *)
- {
- return (m_system == currentSystem);
- }
- OsRule(RuleAction result, OpSys system, QString version_regexp)
- : Rule(result), m_system(system), m_version_regexp(version_regexp)
- {
- }
-
-public:
- virtual QJsonObject toJson();
- static std::shared_ptr<OsRule> create(RuleAction result, OpSys system,
- QString version_regexp)
- {
- return std::shared_ptr<OsRule>(new OsRule(result, system, version_regexp));
- }
-};
-
-class ImplicitRule : public Rule
-{
-protected:
- virtual bool applies(const Library *)
- {
- return true;
- }
- ImplicitRule(RuleAction result) : Rule(result)
- {
- }
-
-public:
- virtual QJsonObject toJson();
- static std::shared_ptr<ImplicitRule> create(RuleAction result)
- {
- return std::shared_ptr<ImplicitRule>(new ImplicitRule(result));
- }
-};
diff --git a/libraries/logic/minecraft/VersionBuildError.h b/libraries/logic/minecraft/VersionBuildError.h
deleted file mode 100644
index fda453e5..00000000
--- a/libraries/logic/minecraft/VersionBuildError.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "Exception.h"
-
-class VersionBuildError : public Exception
-{
-public:
- explicit VersionBuildError(QString cause) : Exception(cause) {}
- virtual ~VersionBuildError() noexcept
- {
- }
-};
-
-/**
- * the base version file was meant for a newer version of the vanilla launcher than we support
- */
-class LauncherVersionError : public VersionBuildError
-{
-public:
- LauncherVersionError(int actual, int supported)
- : VersionBuildError(QObject::tr(
- "The base version file of this instance was meant for a newer (%1) "
- "version of the vanilla launcher than this version of MultiMC supports (%2).")
- .arg(actual)
- .arg(supported)) {};
- virtual ~LauncherVersionError() noexcept
- {
- }
-};
-
-/**
- * some patch was intended for a different version of minecraft
- */
-class MinecraftVersionMismatch : public VersionBuildError
-{
-public:
- MinecraftVersionMismatch(QString fileId, QString mcVersion, QString parentMcVersion)
- : VersionBuildError(QObject::tr("The patch %1 is for a different version of Minecraft "
- "(%2) than that of the instance (%3).")
- .arg(fileId)
- .arg(mcVersion)
- .arg(parentMcVersion)) {};
- virtual ~MinecraftVersionMismatch() noexcept
- {
- }
-};
-
-/**
- * files required for the version are not (yet?) present
- */
-class VersionIncomplete : public VersionBuildError
-{
-public:
- VersionIncomplete(QString missingPatch)
- : VersionBuildError(QObject::tr("Version is incomplete: missing %1.")
- .arg(missingPatch)) {};
- virtual ~VersionIncomplete() noexcept
- {
- }
-};
diff --git a/libraries/logic/minecraft/VersionFile.cpp b/libraries/logic/minecraft/VersionFile.cpp
deleted file mode 100644
index 573c4cb4..00000000
--- a/libraries/logic/minecraft/VersionFile.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <QJsonArray>
-#include <QJsonDocument>
-
-#include <QDebug>
-
-#include "minecraft/VersionFile.h"
-#include "minecraft/Library.h"
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/JarMod.h"
-#include "ParseUtils.h"
-
-#include "VersionBuildError.h"
-#include <Version.h>
-
-bool VersionFile::isMinecraftVersion()
-{
- return fileId == "net.minecraft";
-}
-
-bool VersionFile::hasJarMods()
-{
- return !jarMods.isEmpty();
-}
-
-void VersionFile::applyTo(MinecraftProfile *profile)
-{
- auto theirVersion = profile->getMinecraftVersion();
- if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull())
- {
- if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1)
- {
- throw MinecraftVersionMismatch(fileId, dependsOnMinecraftVersion, theirVersion);
- }
- }
- profile->applyMinecraftVersion(minecraftVersion);
- profile->applyMainClass(mainClass);
- profile->applyAppletClass(appletClass);
- profile->applyMinecraftArguments(minecraftArguments);
- if (isMinecraftVersion())
- {
- profile->applyMinecraftVersionType(type);
- }
- profile->applyMinecraftAssets(mojangAssetIndex);
- profile->applyTweakers(addTweakers);
-
- profile->applyJarMods(jarMods);
- profile->applyTraits(traits);
-
- for (auto library : libraries)
- {
- profile->applyLibrary(library);
- }
- profile->applyProblemSeverity(getProblemSeverity());
- auto iter = mojangDownloads.begin();
- while(iter != mojangDownloads.end())
- {
- profile->applyMojangDownload(iter.key(), iter.value());
- iter++;
- }
-}
diff --git a/libraries/logic/minecraft/VersionFile.h b/libraries/logic/minecraft/VersionFile.h
deleted file mode 100644
index 1b692f0f..00000000
--- a/libraries/logic/minecraft/VersionFile.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QStringList>
-#include <QDateTime>
-#include <QSet>
-
-#include <memory>
-#include "minecraft/OpSys.h"
-#include "minecraft/Rule.h"
-#include "ProfilePatch.h"
-#include "Library.h"
-#include "JarMod.h"
-
-class MinecraftProfile;
-class VersionFile;
-struct MojangDownloadInfo;
-struct MojangAssetIndexInfo;
-
-typedef std::shared_ptr<VersionFile> VersionFilePtr;
-class VersionFile : public ProfilePatch
-{
- friend class MojangVersionFormat;
- friend class OneSixVersionFormat;
-public: /* methods */
- virtual void applyTo(MinecraftProfile *profile) override;
- virtual bool isMinecraftVersion() override;
- virtual bool hasJarMods() override;
- virtual int getOrder() override
- {
- return order;
- }
- virtual void setOrder(int order) override
- {
- this->order = order;
- }
- virtual QList<JarmodPtr> getJarMods() override
- {
- return jarMods;
- }
- virtual QString getID() override
- {
- return fileId;
- }
- virtual QString getName() override
- {
- return name;
- }
- virtual QString getVersion() override
- {
- return version;
- }
- virtual QString getFilename() override
- {
- return filename;
- }
- virtual QDateTime getReleaseDateTime() override
- {
- return m_releaseTime;
- }
- VersionSource getVersionSource() override
- {
- return Local;
- }
-
- std::shared_ptr<class VersionFile> getVersionFile() override
- {
- return std::dynamic_pointer_cast<VersionFile>(shared_from_this());
- }
-
- virtual bool isCustom() override
- {
- return !m_isVanilla;
- };
- virtual bool isCustomizable() override
- {
- return m_isCustomizable;
- }
- virtual bool isRemovable() override
- {
- return m_isRemovable;
- }
- virtual bool isRevertible() override
- {
- return m_isRevertible;
- }
- virtual bool isMoveable() override
- {
- return m_isMovable;
- }
- virtual bool isEditable() override
- {
- return isCustom();
- }
- virtual bool isVersionChangeable() override
- {
- return false;
- }
-
- void setVanilla (bool state)
- {
- m_isVanilla = state;
- }
- void setRemovable (bool state)
- {
- m_isRemovable = state;
- }
- void setRevertible (bool state)
- {
- m_isRevertible = state;
- }
- void setCustomizable (bool state)
- {
- m_isCustomizable = state;
- }
- void setMovable (bool state)
- {
- m_isMovable = state;
- }
-
-
-public: /* data */
- /// MultiMC: order hint for this version file if no explicit order is set
- int order = 0;
-
- // Flags for UI and version file manipulation in general
- bool m_isVanilla = false;
- bool m_isRemovable = false;
- bool m_isRevertible = false;
- bool m_isCustomizable = false;
- bool m_isMovable = false;
-
- /// MultiMC: filename of the file this was loaded from
- QString filename;
-
- /// MultiMC: human readable name of this package
- QString name;
-
- /// MultiMC: package ID of this package
- QString fileId;
-
- /// MultiMC: version of this package
- QString version;
-
- /// MultiMC: dependency on a Minecraft version
- QString dependsOnMinecraftVersion;
-
- /// Mojang: used to version the Mojang version format
- int minimumLauncherVersion = -1;
-
- /// Mojang: version of Minecraft this is
- QString minecraftVersion;
-
- /// Mojang: class to launch Minecraft with
- QString mainClass;
-
- /// MultiMC: DEPRECATED class to launch legacy Minecraft with (ambed in a custom window)
- QString appletClass;
-
- /// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
- QString minecraftArguments;
-
- /// Mojang: type of the Minecraft version
- QString type;
-
- /// Mojang: the time this version was actually released by Mojang
- QDateTime m_releaseTime;
-
- /// Mojang: the time this version was last updated by Mojang
- QDateTime m_updateTime;
-
- /// Mojang: DEPRECATED asset group to be used with Minecraft
- QString assets;
-
- /// MultiMC: list of tweaker mod arguments for launchwrapper
- QStringList addTweakers;
-
- /// Mojang: list of libraries to add to the version
- QList<LibraryPtr> libraries;
-
- /// MultiMC: list of attached traits of this version file - used to enable features
- QSet<QString> traits;
-
- /// MultiMC: list of jar mods added to this version
- QList<JarmodPtr> jarMods;
-
-public:
- // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more.
- QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
-
- // Mojang: extended asset index download information
- std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex;
-};
-
-
diff --git a/libraries/logic/minecraft/VersionFilterData.cpp b/libraries/logic/minecraft/VersionFilterData.cpp
deleted file mode 100644
index 0c4a6e3d..00000000
--- a/libraries/logic/minecraft/VersionFilterData.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "VersionFilterData.h"
-#include "ParseUtils.h"
-
-VersionFilterData g_VersionFilterData = VersionFilterData();
-
-VersionFilterData::VersionFilterData()
-{
- // 1.3.*
- auto libs13 =
- QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}};
-
- fmlLibsMapping["1.3.2"] = libs13;
-
- // 1.4.*
- auto libs14 = QList<FMLlib>{
- {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false},
- {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}};
-
- fmlLibsMapping["1.4"] = libs14;
- fmlLibsMapping["1.4.1"] = libs14;
- fmlLibsMapping["1.4.2"] = libs14;
- fmlLibsMapping["1.4.3"] = libs14;
- fmlLibsMapping["1.4.4"] = libs14;
- fmlLibsMapping["1.4.5"] = libs14;
- fmlLibsMapping["1.4.6"] = libs14;
- fmlLibsMapping["1.4.7"] = libs14;
-
- // 1.5
- fmlLibsMapping["1.5"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
-
- // 1.5.1
- fmlLibsMapping["1.5.1"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
-
- // 1.5.2
- fmlLibsMapping["1.5.2"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
-
- // don't use installers for those.
- forgeInstallerBlacklist = QSet<QString>({"1.5.2"});
- // these won't show up in version lists because they are extremely bad and dangerous
- legacyBlacklist = QSet<QString>({"rd-160052"});
- /*
- * nothing older than this will be accepted from Mojang servers
- * (these versions need to be tested by us first)
- */
- legacyCutoffDate = timeFromS3Time("2013-06-25T15:08:56+02:00");
- lwjglWhitelist =
- QSet<QString>{"net.java.jinput:jinput", "net.java.jinput:jinput-platform",
- "net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl",
- "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"};
-
- // Version list magic
- recommendedMinecraftVersion = "1.7.10";
-}
diff --git a/libraries/logic/minecraft/VersionFilterData.h b/libraries/logic/minecraft/VersionFilterData.h
deleted file mode 100644
index f7d4ebe7..00000000
--- a/libraries/logic/minecraft/VersionFilterData.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-#include <QMap>
-#include <QString>
-#include <QSet>
-#include <QDateTime>
-
-#include "multimc_logic_export.h"
-
-struct FMLlib
-{
- QString filename;
- QString checksum;
- bool ours;
-};
-
-struct VersionFilterData
-{
- VersionFilterData();
- // mapping between minecraft versions and FML libraries required
- QMap<QString, QList<FMLlib>> fmlLibsMapping;
- // set of minecraft versions for which using forge installers is blacklisted
- QSet<QString> forgeInstallerBlacklist;
- // set of 'legacy' versions that will not show up in the version lists.
- QSet<QString> legacyBlacklist;
- // no new versions below this date will be accepted from Mojang servers
- QDateTime legacyCutoffDate;
- // Libraries that belong to LWJGL
- QSet<QString> lwjglWhitelist;
- // Currently recommended minecraft version
- QString recommendedMinecraftVersion;
-};
-extern VersionFilterData MULTIMC_LOGIC_EXPORT g_VersionFilterData;
diff --git a/libraries/logic/minecraft/World.cpp b/libraries/logic/minecraft/World.cpp
deleted file mode 100644
index 6081a8ec..00000000
--- a/libraries/logic/minecraft/World.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/* Copyright 2015 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 <QDir>
-#include <QString>
-#include <QDebug>
-#include <QSaveFile>
-#include "World.h"
-
-#include "GZip.h"
-#include <MMCZip.h>
-#include <FileSystem.h>
-#include <sstream>
-#include <io/stream_reader.h>
-#include <tag_string.h>
-#include <tag_primitive.h>
-#include <quazip.h>
-#include <quazipfile.h>
-#include <quazipdir.h>
-
-std::unique_ptr <nbt::tag_compound> parseLevelDat(QByteArray data)
-{
- QByteArray output;
- if(!GZip::unzip(data, output))
- {
- return nullptr;
- }
- std::istringstream foo(std::string(output.constData(), output.size()));
- auto pair = nbt::io::read_compound(foo);
-
- if(pair.first != "")
- return nullptr;
-
- if(pair.second == nullptr)
- return nullptr;
-
- return std::move(pair.second);
-}
-
-QByteArray serializeLevelDat(nbt::tag_compound * levelInfo)
-{
- std::ostringstream s;
- nbt::io::write_tag("", *levelInfo, s);
- QByteArray val( s.str().data(), (int) s.str().size() );
- return val;
-}
-
-QString getLevelDatFromFS(const QFileInfo &file)
-{
- QDir worldDir(file.filePath());
- if(!file.isDir() || !worldDir.exists("level.dat"))
- {
- return QString();
- }
- return worldDir.absoluteFilePath("level.dat");
-}
-
-QByteArray getLevelDatDataFromFS(const QFileInfo &file)
-{
- auto fullFilePath = getLevelDatFromFS(file);
- if(fullFilePath.isNull())
- {
- return QByteArray();
- }
- QFile f(fullFilePath);
- if(!f.open(QIODevice::ReadOnly))
- {
- return QByteArray();
- }
- return f.readAll();
-}
-
-bool putLevelDatDataToFS(const QFileInfo &file, QByteArray & data)
-{
- auto fullFilePath = getLevelDatFromFS(file);
- if(fullFilePath.isNull())
- {
- return false;
- }
- QSaveFile f(fullFilePath);
- if(!f.open(QIODevice::WriteOnly))
- {
- return false;
- }
- QByteArray compressed;
- if(!GZip::zip(data, compressed))
- {
- return false;
- }
- if(f.write(compressed) != compressed.size())
- {
- f.cancelWriting();
- return false;
- }
- return f.commit();
-}
-
-World::World(const QFileInfo &file)
-{
- repath(file);
-}
-
-void World::repath(const QFileInfo &file)
-{
- m_containerFile = file;
- m_folderName = file.fileName();
- if(file.isFile() && file.suffix() == "zip")
- {
- readFromZip(file);
- }
- else if(file.isDir())
- {
- readFromFS(file);
- }
-}
-
-void World::readFromFS(const QFileInfo &file)
-{
- auto bytes = getLevelDatDataFromFS(file);
- if(bytes.isEmpty())
- {
- is_valid = false;
- return;
- }
- loadFromLevelDat(bytes);
- levelDatTime = file.lastModified();
-}
-
-void World::readFromZip(const QFileInfo &file)
-{
- QuaZip zip(file.absoluteFilePath());
- is_valid = zip.open(QuaZip::mdUnzip);
- if (!is_valid)
- {
- return;
- }
- auto location = MMCZip::findFileInZip(&zip, "level.dat");
- is_valid = !location.isEmpty();
- if (!is_valid)
- {
- return;
- }
- m_containerOffsetPath = location;
- QuaZipFile zippedFile(&zip);
- // read the install profile
- is_valid = zip.setCurrentFile(location + "level.dat");
- if (!is_valid)
- {
- return;
- }
- is_valid = zippedFile.open(QIODevice::ReadOnly);
- QuaZipFileInfo64 levelDatInfo;
- zippedFile.getFileInfo(&levelDatInfo);
- auto modTime = levelDatInfo.getNTFSmTime();
- if(!modTime.isValid())
- {
- modTime = levelDatInfo.dateTime;
- }
- levelDatTime = modTime;
- if (!is_valid)
- {
- return;
- }
- loadFromLevelDat(zippedFile.readAll());
- zippedFile.close();
-}
-
-bool World::install(const QString &to, const QString &name)
-{
- auto finalPath = FS::PathCombine(to, FS::DirNameFromString(m_actualName, to));
- if(!FS::ensureFolderPathExists(finalPath))
- {
- return false;
- }
- bool ok = false;
- if(m_containerFile.isFile())
- {
- QuaZip zip(m_containerFile.absoluteFilePath());
- if (!zip.open(QuaZip::mdUnzip))
- {
- return false;
- }
- ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath).isEmpty();
- }
- else if(m_containerFile.isDir())
- {
- QString from = m_containerFile.filePath();
- ok = FS::copy(from, finalPath)();
- }
-
- if(ok && !name.isEmpty() && m_actualName != name)
- {
- World newWorld(finalPath);
- if(newWorld.isValid())
- {
- newWorld.rename(name);
- }
- }
- return ok;
-}
-
-bool World::rename(const QString &newName)
-{
- if(m_containerFile.isFile())
- {
- return false;
- }
-
- auto data = getLevelDatDataFromFS(m_containerFile);
- if(data.isEmpty())
- {
- return false;
- }
-
- auto worldData = parseLevelDat(data);
- if(!worldData)
- {
- return false;
- }
- auto &val = worldData->at("Data");
- if(val.get_type() != nbt::tag_type::Compound)
- {
- return false;
- }
- auto &dataCompound = val.as<nbt::tag_compound>();
- dataCompound.put("LevelName", nbt::value_initializer(newName.toUtf8().data()));
- data = serializeLevelDat(worldData.get());
-
- putLevelDatDataToFS(m_containerFile, data);
-
- m_actualName = newName;
-
- QDir parentDir(m_containerFile.absoluteFilePath());
- parentDir.cdUp();
- QFile container(m_containerFile.absoluteFilePath());
- auto dirName = FS::DirNameFromString(m_actualName, parentDir.absolutePath());
- container.rename(parentDir.absoluteFilePath(dirName));
-
- return true;
-}
-
-static QString read_string (nbt::value& parent, const char * name, const QString & fallback = QString())
-{
- try
- {
- auto &namedValue = parent.at(name);
- if(namedValue.get_type() != nbt::tag_type::String)
- {
- return fallback;
- }
- auto & tag_str = namedValue.as<nbt::tag_string>();
- return QString::fromStdString(tag_str.get());
- }
- catch(std::out_of_range e)
- {
- // fallback for old world formats
- qWarning() << "String NBT tag" << name << "could not be found. Defaulting to" << fallback;
- return fallback;
- }
- catch(std::bad_cast e)
- {
- // type mismatch
- qWarning() << "NBT tag" << name << "could not be converted to string. Defaulting to" << fallback;
- return fallback;
- }
-};
-
-static int64_t read_long (nbt::value& parent, const char * name, const int64_t & fallback = 0)
-{
- try
- {
- auto &namedValue = parent.at(name);
- if(namedValue.get_type() != nbt::tag_type::Long)
- {
- return fallback;
- }
- auto & tag_str = namedValue.as<nbt::tag_long>();
- return tag_str.get();
- }
- catch(std::out_of_range e)
- {
- // fallback for old world formats
- qWarning() << "Long NBT tag" << name << "could not be found. Defaulting to" << fallback;
- return fallback;
- }
- catch(std::bad_cast e)
- {
- // type mismatch
- qWarning() << "NBT tag" << name << "could not be converted to long. Defaulting to" << fallback;
- return fallback;
- }
-};
-
-void World::loadFromLevelDat(QByteArray data)
-{
- try
- {
- auto levelData = parseLevelDat(data);
- if(!levelData)
- {
- is_valid = false;
- return;
- }
-
- auto &val = levelData->at("Data");
- is_valid = val.get_type() == nbt::tag_type::Compound;
- if(!is_valid)
- return;
-
- m_actualName = read_string(val, "LevelName", m_folderName);
-
-
- int64_t temp = read_long(val, "LastPlayed", 0);
- if(temp == 0)
- {
- m_lastPlayed = levelDatTime;
- }
- else
- {
- m_lastPlayed = QDateTime::fromMSecsSinceEpoch(temp);
- }
-
- m_randomSeed = read_long(val, "RandomSeed", 0);
-
- qDebug() << "World Name:" << m_actualName;
- qDebug() << "Last Played:" << m_lastPlayed.toString();
- qDebug() << "Seed:" << m_randomSeed;
- }
- catch (nbt::io::input_error e)
- {
- qWarning() << "Unable to load" << m_folderName << ":" << e.what();
- is_valid = false;
- return;
- }
-}
-
-bool World::replace(World &with)
-{
- if (!destroy())
- return false;
- bool success = FS::copy(with.m_containerFile.filePath(), m_containerFile.path())();
- if (success)
- {
- m_folderName = with.m_folderName;
- m_containerFile.refresh();
- }
- return success;
-}
-
-bool World::destroy()
-{
- if(!is_valid) return false;
- if (m_containerFile.isDir())
- {
- QDir d(m_containerFile.filePath());
- return d.removeRecursively();
- }
- else if(m_containerFile.isFile())
- {
- QFile file(m_containerFile.absoluteFilePath());
- return file.remove();
- }
- return true;
-}
-
-bool World::operator==(const World &other) const
-{
- return is_valid == other.is_valid && folderName() == other.folderName();
-}
-bool World::strongCompare(const World &other) const
-{
- return is_valid == other.is_valid && folderName() == other.folderName();
-}
diff --git a/libraries/logic/minecraft/World.h b/libraries/logic/minecraft/World.h
deleted file mode 100644
index 3cde5ea4..00000000
--- a/libraries/logic/minecraft/World.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <QFileInfo>
-#include <QDateTime>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT World
-{
-public:
- World(const QFileInfo &file);
- QString folderName() const
- {
- return m_folderName;
- }
- QString name() const
- {
- return m_actualName;
- }
- QDateTime lastPlayed() const
- {
- return m_lastPlayed;
- }
- int64_t seed() const
- {
- return m_randomSeed;
- }
- bool isValid() const
- {
- return is_valid;
- }
- bool isOnFS() const
- {
- return m_containerFile.isDir();
- }
- QFileInfo container() const
- {
- return m_containerFile;
- }
- // delete all the files of this world
- bool destroy();
- // replace this world with a copy of the other
- bool replace(World &with);
- // change the world's filesystem path (used by world lists for *MAGIC* purposes)
- void repath(const QFileInfo &file);
-
- bool rename(const QString &to);
- bool install(const QString &to, const QString &name= QString());
-
- // WEAK compare operator - used for replacing worlds
- bool operator==(const World &other) const;
- bool strongCompare(const World &other) const;
-
-private:
- void readFromZip(const QFileInfo &file);
- void readFromFS(const QFileInfo &file);
- void loadFromLevelDat(QByteArray data);
-
-protected:
-
- QFileInfo m_containerFile;
- QString m_containerOffsetPath;
- QString m_folderName;
- QString m_actualName;
- QDateTime levelDatTime;
- QDateTime m_lastPlayed;
- int64_t m_randomSeed = 0;
- bool is_valid = false;
-};
diff --git a/libraries/logic/minecraft/WorldList.cpp b/libraries/logic/minecraft/WorldList.cpp
deleted file mode 100644
index 42c8a3e6..00000000
--- a/libraries/logic/minecraft/WorldList.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/* Copyright 2015 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 "WorldList.h"
-#include <FileSystem.h>
-#include <QMimeData>
-#include <QUrl>
-#include <QUuid>
-#include <QString>
-#include <QFileSystemWatcher>
-#include <QDebug>
-
-WorldList::WorldList(const QString &dir)
- : QAbstractListModel(), m_dir(dir)
-{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_watcher = new QFileSystemWatcher(this);
- is_watching = false;
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
- SLOT(directoryChanged(QString)));
-}
-
-void WorldList::startWatching()
-{
- update();
- is_watching = m_watcher->addPath(m_dir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_dir.absolutePath();
- }
-}
-
-void WorldList::stopWatching()
-{
- is_watching = !m_watcher->removePath(m_dir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_dir.absolutePath();
- }
-}
-
-bool WorldList::update()
-{
- if (!isValid())
- return false;
-
- QList<World> newWorlds;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- // if there are any untracked files...
- for (QFileInfo entry : folderContents)
- {
- if(!entry.isDir())
- continue;
-
- World w(entry);
- if(w.isValid())
- {
- newWorlds.append(w);
- }
- }
- beginResetModel();
- worlds.swap(newWorlds);
- endResetModel();
- return true;
-}
-
-void WorldList::directoryChanged(QString path)
-{
- update();
-}
-
-bool WorldList::isValid()
-{
- return m_dir.exists() && m_dir.isReadable();
-}
-
-bool WorldList::deleteWorld(int index)
-{
- if (index >= worlds.size() || index < 0)
- return false;
- World &m = worlds[index];
- if (m.destroy())
- {
- beginRemoveRows(QModelIndex(), index, index);
- worlds.removeAt(index);
- endRemoveRows();
- emit changed();
- return true;
- }
- return false;
-}
-
-bool WorldList::deleteWorlds(int first, int last)
-{
- for (int i = first; i <= last; i++)
- {
- World &m = worlds[i];
- m.destroy();
- }
- beginRemoveRows(QModelIndex(), first, last);
- worlds.erase(worlds.begin() + first, worlds.begin() + last + 1);
- endRemoveRows();
- emit changed();
- return true;
-}
-
-int WorldList::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-QVariant WorldList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= worlds.size())
- return QVariant();
-
- auto & world = worlds[row];
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return world.name();
-
- case LastPlayedColumn:
- return world.lastPlayed();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- {
- return world.folderName();
- }
- case ObjectRole:
- {
- return QVariant::fromValue<void *>((void *)&world);
- }
- case FolderRole:
- {
- return QDir::toNativeSeparators(dir().absoluteFilePath(world.folderName()));
- }
- case SeedRole:
- {
- return qVariantFromValue<qlonglong>(world.seed());
- }
- case NameRole:
- {
- return world.name();
- }
- case LastPlayedRole:
- {
- return world.lastPlayed();
- }
- default:
- return QVariant();
- }
-}
-
-QVariant WorldList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case NameColumn:
- return tr("Name");
- case LastPlayedColumn:
- return tr("Last Played");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return tr("The name of the world.");
- case LastPlayedColumn:
- return tr("Date and time the world was last played.");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
-}
-
-QStringList WorldList::mimeTypes() const
-{
- QStringList types;
- types << "text/uri-list";
- return types;
-}
-
-class WorldMimeData : public QMimeData
-{
-Q_OBJECT
-
-public:
- WorldMimeData(QList<World> worlds)
- {
- m_worlds = worlds;
-
- }
- QStringList formats() const
- {
- return QMimeData::formats() << "text/uri-list";
- }
-
-protected:
- QVariant retrieveData(const QString &mimetype, QVariant::Type type) const
- {
- QList<QUrl> urls;
- for(auto &world: m_worlds)
- {
- if(!world.isValid() || !world.isOnFS())
- continue;
- QString worldPath = world.container().absoluteFilePath();
- qDebug() << worldPath;
- urls.append(QUrl::fromLocalFile(worldPath));
- }
- const_cast<WorldMimeData*>(this)->setUrls(urls);
- return QMimeData::retrieveData(mimetype, type);
- }
-private:
- QList<World> m_worlds;
-};
-
-QMimeData *WorldList::mimeData(const QModelIndexList &indexes) const
-{
- if (indexes.size() == 0)
- return new QMimeData();
-
- QList<World> worlds;
- for(auto idx : indexes)
- {
- if(idx.column() != 0)
- continue;
- int row = idx.row();
- if (row < 0 || row >= this->worlds.size())
- continue;
- worlds.append(this->worlds[row]);
- }
- if(!worlds.size())
- {
- return new QMimeData();
- }
- return new WorldMimeData(worlds);
-}
-
-Qt::ItemFlags WorldList::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
-}
-
-Qt::DropActions WorldList::supportedDragActions() const
-{
- // move to other mod lists or VOID
- return Qt::MoveAction;
-}
-
-Qt::DropActions WorldList::supportedDropActions() const
-{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
-}
-
-void WorldList::installWorld(QFileInfo filename)
-{
- qDebug() << "installing: " << filename.absoluteFilePath();
- World w(filename);
- if(!w.isValid())
- {
- return;
- }
- w.install(m_dir.absolutePath());
-}
-
-bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
-{
- if (action == Qt::IgnoreAction)
- return true;
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- return false;
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- stopWatching();
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- continue;
- QString filename = url.toLocalFile();
-
- QFileInfo worldInfo(filename);
-
- if(!m_dir.entryInfoList().contains(worldInfo))
- {
- installWorld(worldInfo);
- }
- }
- if (was_watching)
- startWatching();
- return true;
- }
- return false;
-}
-
-#include "WorldList.moc"
diff --git a/libraries/logic/minecraft/WorldList.h b/libraries/logic/minecraft/WorldList.h
deleted file mode 100644
index 34b30e9c..00000000
--- a/libraries/logic/minecraft/WorldList.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QList>
-#include <QString>
-#include <QDir>
-#include <QAbstractListModel>
-#include <QMimeData>
-#include "minecraft/World.h"
-
-#include "multimc_logic_export.h"
-
-class QFileSystemWatcher;
-
-class MULTIMC_LOGIC_EXPORT WorldList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum Columns
- {
- NameColumn,
- LastPlayedColumn
- };
-
- enum Roles
- {
- ObjectRole = Qt::UserRole + 1,
- FolderRole,
- SeedRole,
- NameRole,
- LastPlayedRole
- };
-
- WorldList(const QString &dir);
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- return size();
- };
- virtual QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
- size_t size() const
- {
- return worlds.size();
- };
- bool empty() const
- {
- return size() == 0;
- }
- World &operator[](size_t index)
- {
- return worlds[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /// Install a world from location
- void installWorld(QFileInfo filename);
-
- /// Deletes the mod at the given index.
- virtual bool deleteWorld(int index);
-
- /// Deletes all the selected mods
- virtual bool deleteWorlds(int first, int last);
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- /// get data for drag action
- virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
- /// get the supported mime types
- virtual QStringList mimeTypes() const;
- /// process data from drop action
- virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
- /// what drag actions do we support?
- virtual Qt::DropActions supportedDragActions() const;
-
- /// what drop actions do we support?
- virtual Qt::DropActions supportedDropActions() const;
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir() const
- {
- return m_dir;
- }
-
- const QList<World> &allWorlds() const
- {
- return worlds;
- }
-
-private slots:
- void directoryChanged(QString path);
-
-signals:
- void changed();
-
-protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching;
- QDir m_dir;
- QList<World> worlds;
-};
diff --git a/libraries/logic/minecraft/auth/AuthSession.cpp b/libraries/logic/minecraft/auth/AuthSession.cpp
deleted file mode 100644
index 8758bfbd..00000000
--- a/libraries/logic/minecraft/auth/AuthSession.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "AuthSession.h"
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonDocument>
-#include <QStringList>
-
-QString AuthSession::serializeUserProperties()
-{
- QJsonObject userAttrs;
- for (auto key : u.properties.keys())
- {
- auto array = QJsonArray::fromStringList(u.properties.values(key));
- userAttrs.insert(key, array);
- }
- QJsonDocument value(userAttrs);
- return value.toJson(QJsonDocument::Compact);
-
-}
-
-bool AuthSession::MakeOffline(QString offline_playername)
-{
- if (status != PlayableOffline && status != PlayableOnline)
- {
- return false;
- }
- session = "-";
- player_name = offline_playername;
- status = PlayableOffline;
- return true;
-}
diff --git a/libraries/logic/minecraft/auth/AuthSession.h b/libraries/logic/minecraft/auth/AuthSession.h
deleted file mode 100644
index dede90a9..00000000
--- a/libraries/logic/minecraft/auth/AuthSession.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QMultiMap>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-struct User
-{
- QString id;
- QMultiMap<QString, QString> properties;
-};
-
-struct MULTIMC_LOGIC_EXPORT AuthSession
-{
- bool MakeOffline(QString offline_playername);
-
- QString serializeUserProperties();
-
- enum Status
- {
- Undetermined,
- RequiresPassword,
- PlayableOffline,
- PlayableOnline
- } status = Undetermined;
-
- User u;
-
- // client token
- QString client_token;
- // account user name
- QString username;
- // combined session ID
- QString session;
- // volatile auth token
- QString access_token;
- // profile name
- QString player_name;
- // profile ID
- QString uuid;
- // 'legacy' or 'mojang', depending on account type
- QString user_type;
- // Did the auth server reply?
- bool auth_server_online = false;
- // Did the user request online mode?
- bool wants_online = true;
-};
-
-typedef std::shared_ptr<AuthSession> AuthSessionPtr;
diff --git a/libraries/logic/minecraft/auth/MojangAccount.cpp b/libraries/logic/minecraft/auth/MojangAccount.cpp
deleted file mode 100644
index 69a24c09..00000000
--- a/libraries/logic/minecraft/auth/MojangAccount.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
- *
- * 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 "MojangAccount.h"
-#include "flows/RefreshTask.h"
-#include "flows/AuthenticateTask.h"
-
-#include <QUuid>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QRegExp>
-#include <QStringList>
-#include <QJsonDocument>
-
-#include <QDebug>
-
-MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object)
-{
- // The JSON object must at least have a username for it to be valid.
- if (!object.value("username").isString())
- {
- qCritical() << "Can't load Mojang account info from JSON object. Username field is "
- "missing or of the wrong type.";
- return nullptr;
- }
-
- QString username = object.value("username").toString("");
- QString clientToken = object.value("clientToken").toString("");
- QString accessToken = object.value("accessToken").toString("");
-
- QJsonArray profileArray = object.value("profiles").toArray();
- if (profileArray.size() < 1)
- {
- qCritical() << "Can't load Mojang account with username \"" << username
- << "\". No profiles found.";
- return nullptr;
- }
-
- QList<AccountProfile> profiles;
- for (QJsonValue profileVal : profileArray)
- {
- QJsonObject profileObject = profileVal.toObject();
- QString id = profileObject.value("id").toString("");
- QString name = profileObject.value("name").toString("");
- bool legacy = profileObject.value("legacy").toBool(false);
- if (id.isEmpty() || name.isEmpty())
- {
- qWarning() << "Unable to load a profile because it was missing an ID or a name.";
- continue;
- }
- profiles.append({id, name, legacy});
- }
-
- MojangAccountPtr account(new MojangAccount());
- if (object.value("user").isObject())
- {
- User u;
- QJsonObject userStructure = object.value("user").toObject();
- u.id = userStructure.value("id").toString();
- /*
- QJsonObject propMap = userStructure.value("properties").toObject();
- for(auto key: propMap.keys())
- {
- auto values = propMap.operator[](key).toArray();
- for(auto value: values)
- u.properties.insert(key, value.toString());
- }
- */
- account->m_user = u;
- }
- account->m_username = username;
- account->m_clientToken = clientToken;
- account->m_accessToken = accessToken;
- account->m_profiles = profiles;
-
- // Get the currently selected profile.
- QString currentProfile = object.value("activeProfile").toString("");
- if (!currentProfile.isEmpty())
- account->setCurrentProfile(currentProfile);
-
- return account;
-}
-
-MojangAccountPtr MojangAccount::createFromUsername(const QString &username)
-{
- MojangAccountPtr account(new MojangAccount());
- account->m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
- account->m_username = username;
- return account;
-}
-
-QJsonObject MojangAccount::saveToJson() const
-{
- QJsonObject json;
- json.insert("username", m_username);
- json.insert("clientToken", m_clientToken);
- json.insert("accessToken", m_accessToken);
-
- QJsonArray profileArray;
- for (AccountProfile profile : m_profiles)
- {
- QJsonObject profileObj;
- profileObj.insert("id", profile.id);
- profileObj.insert("name", profile.name);
- profileObj.insert("legacy", profile.legacy);
- profileArray.append(profileObj);
- }
- json.insert("profiles", profileArray);
-
- QJsonObject userStructure;
- {
- userStructure.insert("id", m_user.id);
- /*
- QJsonObject userAttrs;
- for(auto key: m_user.properties.keys())
- {
- auto array = QJsonArray::fromStringList(m_user.properties.values(key));
- userAttrs.insert(key, array);
- }
- userStructure.insert("properties", userAttrs);
- */
- }
- json.insert("user", userStructure);
-
- if (m_currentProfile != -1)
- json.insert("activeProfile", currentProfile()->id);
-
- return json;
-}
-
-bool MojangAccount::setCurrentProfile(const QString &profileId)
-{
- for (int i = 0; i < m_profiles.length(); i++)
- {
- if (m_profiles[i].id == profileId)
- {
- m_currentProfile = i;
- return true;
- }
- }
- return false;
-}
-
-const AccountProfile *MojangAccount::currentProfile() const
-{
- if (m_currentProfile == -1)
- return nullptr;
- return &m_profiles[m_currentProfile];
-}
-
-AccountStatus MojangAccount::accountStatus() const
-{
- if (m_accessToken.isEmpty())
- return NotVerified;
- else
- return Verified;
-}
-
-std::shared_ptr<YggdrasilTask> MojangAccount::login(AuthSessionPtr session,
- QString password)
-{
- Q_ASSERT(m_currentTask.get() == nullptr);
-
- // take care of the true offline status
- if (accountStatus() == NotVerified && password.isEmpty())
- {
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- fillSession(session);
- }
- return nullptr;
- }
-
- if (password.isEmpty())
- {
- m_currentTask.reset(new RefreshTask(this));
- }
- else
- {
- m_currentTask.reset(new AuthenticateTask(this, password));
- }
- m_currentTask->assignSession(session);
-
- connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
- connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
- return m_currentTask;
-}
-
-void MojangAccount::authSucceeded()
-{
- auto session = m_currentTask->getAssignedSession();
- if (session)
- {
- session->status =
- session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
- fillSession(session);
- session->auth_server_online = true;
- }
- m_currentTask.reset();
- emit changed();
-}
-
-void MojangAccount::authFailed(QString reason)
-{
- auto session = m_currentTask->getAssignedSession();
- // This is emitted when the yggdrasil tasks time out or are cancelled.
- // -> we treat the error as no-op
- if (m_currentTask->state() == YggdrasilTask::STATE_FAILED_SOFT)
- {
- if (session)
- {
- session->status = accountStatus() == Verified ? AuthSession::PlayableOffline
- : AuthSession::RequiresPassword;
- session->auth_server_online = false;
- fillSession(session);
- }
- }
- else
- {
- m_accessToken = QString();
- emit changed();
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- session->auth_server_online = true;
- fillSession(session);
- }
- }
- m_currentTask.reset();
-}
-
-void MojangAccount::fillSession(AuthSessionPtr session)
-{
- // the user name. you have to have an user name
- session->username = m_username;
- // volatile auth token
- session->access_token = m_accessToken;
- // the semi-permanent client token
- session->client_token = m_clientToken;
- if (currentProfile())
- {
- // profile name
- session->player_name = currentProfile()->name;
- // profile ID
- session->uuid = currentProfile()->id;
- // 'legacy' or 'mojang', depending on account type
- session->user_type = currentProfile()->legacy ? "legacy" : "mojang";
- if (!session->access_token.isEmpty())
- {
- session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
- }
- else
- {
- session->session = "-";
- }
- }
- else
- {
- session->player_name = "Player";
- session->session = "-";
- }
- session->u = user();
-}
diff --git a/libraries/logic/minecraft/auth/MojangAccount.h b/libraries/logic/minecraft/auth/MojangAccount.h
deleted file mode 100644
index 2de0c19c..00000000
--- a/libraries/logic/minecraft/auth/MojangAccount.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QString>
-#include <QList>
-#include <QJsonObject>
-#include <QPair>
-#include <QMap>
-
-#include <memory>
-#include "AuthSession.h"
-
-#include "multimc_logic_export.h"
-
-class Task;
-class YggdrasilTask;
-class MojangAccount;
-
-typedef std::shared_ptr<MojangAccount> MojangAccountPtr;
-Q_DECLARE_METATYPE(MojangAccountPtr)
-
-/**
- * A profile within someone's Mojang account.
- *
- * Currently, the profile system has not been implemented by Mojang yet,
- * but we might as well add some things for it in MultiMC right now so
- * we don't have to rip the code to pieces to add it later.
- */
-struct AccountProfile
-{
- QString id;
- QString name;
- bool legacy;
-};
-
-enum AccountStatus
-{
- NotVerified,
- Verified
-};
-
-/**
- * Object that stores information about a certain Mojang account.
- *
- * Said information may include things such as that account's username, client token, and access
- * token if the user chose to stay logged in.
- */
-class MULTIMC_LOGIC_EXPORT MojangAccount : public QObject
-{
- Q_OBJECT
-public: /* construction */
- //! Do not copy accounts. ever.
- explicit MojangAccount(const MojangAccount &other, QObject *parent) = delete;
-
- //! Default constructor
- explicit MojangAccount(QObject *parent = 0) : QObject(parent) {};
-
- //! Creates an empty account for the specified user name.
- static MojangAccountPtr createFromUsername(const QString &username);
-
- //! Loads a MojangAccount from the given JSON object.
- static MojangAccountPtr loadFromJson(const QJsonObject &json);
-
- //! Saves a MojangAccount to a JSON object and returns it.
- QJsonObject saveToJson() const;
-
-public: /* manipulation */
- /**
- * Sets the currently selected profile to the profile with the given ID string.
- * If profileId is not in the list of available profiles, the function will simply return
- * false.
- */
- bool setCurrentProfile(const QString &profileId);
-
- /**
- * Attempt to login. Empty password means we use the token.
- * If the attempt fails because we already are performing some task, it returns false.
- */
- std::shared_ptr<YggdrasilTask> login(AuthSessionPtr session,
- QString password = QString());
-
-public: /* queries */
- const QString &username() const
- {
- return m_username;
- }
-
- const QString &clientToken() const
- {
- return m_clientToken;
- }
-
- const QString &accessToken() const
- {
- return m_accessToken;
- }
-
- const QList<AccountProfile> &profiles() const
- {
- return m_profiles;
- }
-
- const User &user()
- {
- return m_user;
- }
-
- //! Returns the currently selected profile (if none, returns nullptr)
- const AccountProfile *currentProfile() const;
-
- //! Returns whether the account is NotVerified, Verified or Online
- AccountStatus accountStatus() const;
-
-signals:
- /**
- * This signal is emitted when the account changes
- */
- void changed();
-
- // TODO: better signalling for the various possible state changes - especially errors
-
-protected: /* variables */
- QString m_username;
-
- // Used to identify the client - the user can have multiple clients for the same account
- // Think: different launchers, all connecting to the same account/profile
- QString m_clientToken;
-
- // Blank if not logged in.
- QString m_accessToken;
-
- // Index of the selected profile within the list of available
- // profiles. -1 if nothing is selected.
- int m_currentProfile = -1;
-
- // List of available profiles.
- QList<AccountProfile> m_profiles;
-
- // the user structure, whatever it is.
- User m_user;
-
- // current task we are executing here
- std::shared_ptr<YggdrasilTask> m_currentTask;
-
-private
-slots:
- void authSucceeded();
- void authFailed(QString reason);
-
-private:
- void fillSession(AuthSessionPtr session);
-
-public:
- friend class YggdrasilTask;
- friend class AuthenticateTask;
- friend class ValidateTask;
- friend class RefreshTask;
-};
diff --git a/libraries/logic/minecraft/auth/MojangAccountList.cpp b/libraries/logic/minecraft/auth/MojangAccountList.cpp
deleted file mode 100644
index 26cbc81a..00000000
--- a/libraries/logic/minecraft/auth/MojangAccountList.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/* Copyright 2013-2015 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 "MojangAccountList.h"
-#include "MojangAccount.h"
-
-#include <QIODevice>
-#include <QFile>
-#include <QTextStream>
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QJsonObject>
-#include <QJsonParseError>
-#include <QDir>
-
-#include <QDebug>
-
-#include <FileSystem.h>
-
-#define ACCOUNT_LIST_FORMAT_VERSION 2
-
-MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-MojangAccountPtr MojangAccountList::findAccount(const QString &username) const
-{
- for (int i = 0; i < count(); i++)
- {
- MojangAccountPtr account = at(i);
- if (account->username() == username)
- return account;
- }
- return nullptr;
-}
-
-const MojangAccountPtr MojangAccountList::at(int i) const
-{
- return MojangAccountPtr(m_accounts.at(i));
-}
-
-void MojangAccountList::addAccount(const MojangAccountPtr account)
-{
- beginResetModel();
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- endResetModel();
- onListChanged();
-}
-
-void MojangAccountList::removeAccount(const QString &username)
-{
- beginResetModel();
- for (auto account : m_accounts)
- {
- if (account->username() == username)
- {
- m_accounts.removeOne(account);
- return;
- }
- }
- endResetModel();
- onListChanged();
-}
-
-void MojangAccountList::removeAccount(QModelIndex index)
-{
- beginResetModel();
- m_accounts.removeAt(index.row());
- endResetModel();
- onListChanged();
-}
-
-MojangAccountPtr MojangAccountList::activeAccount() const
-{
- return m_activeAccount;
-}
-
-void MojangAccountList::setActiveAccount(const QString &username)
-{
- beginResetModel();
- if (username.isEmpty())
- {
- m_activeAccount = nullptr;
- }
- else
- {
- for (MojangAccountPtr account : m_accounts)
- {
- if (account->username() == username)
- m_activeAccount = account;
- }
- }
- endResetModel();
- onActiveChanged();
-}
-
-void MojangAccountList::accountChanged()
-{
- // the list changed. there is no doubt.
- onListChanged();
-}
-
-void MojangAccountList::onListChanged()
-{
- if (m_autosave)
- // TODO: Alert the user if this fails.
- saveList();
-
- emit listChanged();
-}
-
-void MojangAccountList::onActiveChanged()
-{
- if (m_autosave)
- saveList();
-
- emit activeAccountChanged();
-}
-
-int MojangAccountList::count() const
-{
- return m_accounts.count();
-}
-
-QVariant MojangAccountList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- MojangAccountPtr account = at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case NameColumn:
- return account->username();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return account->username();
-
- case PointerRole:
- return qVariantFromValue(account);
-
- case Qt::CheckStateRole:
- switch (index.column())
- {
- case ActiveColumn:
- return account == m_activeAccount;
- }
-
- default:
- return QVariant();
- }
-}
-
-QVariant MojangAccountList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Active?");
-
- case NameColumn:
- return tr("Name");
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return tr("The name of the version.");
-
- default:
- return QVariant();
- }
-
- default:
- return QVariant();
- }
-}
-
-int MojangAccountList::rowCount(const QModelIndex &parent) const
-{
- // Return count
- return count();
-}
-
-int MojangAccountList::columnCount(const QModelIndex &parent) const
-{
- return 2;
-}
-
-Qt::ItemFlags MojangAccountList::flags(const QModelIndex &index) const
-{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return Qt::NoItemFlags;
- }
-
- return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-}
-
-bool MojangAccountList::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if(role == Qt::CheckStateRole)
- {
- if(value == Qt::Checked)
- {
- MojangAccountPtr account = this->at(index.row());
- this->setActiveAccount(account->username());
- }
- }
-
- emit dataChanged(index, index);
- return true;
-}
-
-void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
-{
- beginResetModel();
- m_accounts = versions;
- endResetModel();
-}
-
-bool MojangAccountList::loadList(const QString &filePath)
-{
- QString path = filePath;
- if (path.isEmpty())
- path = m_listFilePath;
- if (path.isEmpty())
- {
- qCritical() << "Can't load Mojang account list. No file path given and no default set.";
- return false;
- }
-
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::ReadOnly))
- {
- qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
- return false;
- }
-
- // Read the file and close it.
- QByteArray jsonData = file.readAll();
- file.close();
-
- QJsonParseError parseError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
-
- // Fail if the JSON is invalid.
- if (parseError.error != QJsonParseError::NoError)
- {
- qCritical() << QString("Failed to parse account list file: %1 at offset %2")
- .arg(parseError.errorString(), QString::number(parseError.offset))
- .toUtf8();
- return false;
- }
-
- // Make sure the root is an object.
- if (!jsonDoc.isObject())
- {
- qCritical() << "Invalid account list JSON: Root should be an array.";
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Make sure the format version matches.
- if (root.value("formatVersion").toVariant().toInt() != ACCOUNT_LIST_FORMAT_VERSION)
- {
- QString newName = "accounts-old.json";
- qWarning() << "Format version mismatch when loading account list. Existing one will be renamed to"
- << newName;
-
- // Attempt to rename the old version.
- file.rename(newName);
- return false;
- }
-
- // Now, load the accounts array.
- beginResetModel();
- QJsonArray accounts = root.value("accounts").toArray();
- for (QJsonValue accountVal : accounts)
- {
- QJsonObject accountObj = accountVal.toObject();
- MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
- if (account.get() != nullptr)
- {
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- }
- else
- {
- qWarning() << "Failed to load an account.";
- }
- }
- // Load the active account.
- m_activeAccount = findAccount(root.value("activeAccount").toString(""));
- endResetModel();
- return true;
-}
-
-bool MojangAccountList::saveList(const QString &filePath)
-{
- QString path(filePath);
- if (path.isEmpty())
- path = m_listFilePath;
- if (path.isEmpty())
- {
- qCritical() << "Can't save Mojang account list. No file path given and no default set.";
- return false;
- }
-
- // make sure the parent folder exists
- if(!FS::ensureFilePathExists(path))
- return false;
-
- // make sure the file wasn't overwritten with a folder before (fixes a bug)
- QFileInfo finfo(path);
- if(finfo.isDir())
- {
- QDir badDir(path);
- badDir.removeRecursively();
- }
-
- qDebug() << "Writing account list to" << path;
-
- qDebug() << "Building JSON data structure.";
- // Build the JSON document to write to the list file.
- QJsonObject root;
-
- root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION);
-
- // Build a list of accounts.
- qDebug() << "Building account array.";
- QJsonArray accounts;
- for (MojangAccountPtr account : m_accounts)
- {
- QJsonObject accountObj = account->saveToJson();
- accounts.append(accountObj);
- }
-
- // Insert the account list into the root object.
- root.insert("accounts", accounts);
-
- if(m_activeAccount)
- {
- // Save the active account.
- root.insert("activeAccount", m_activeAccount->username());
- }
-
- // Create a JSON document object to convert our JSON to bytes.
- QJsonDocument doc(root);
-
- // Now that we're done building the JSON object, we can write it to the file.
- qDebug() << "Writing account list to file.";
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::WriteOnly))
- {
- qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
- return false;
- }
-
- // Write the JSON to the file.
- file.write(doc.toJson());
- file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser);
- file.close();
-
- qDebug() << "Saved account list to" << path;
-
- return true;
-}
-
-void MojangAccountList::setListFilePath(QString path, bool autosave)
-{
- m_listFilePath = path;
- m_autosave = autosave;
-}
-
-bool MojangAccountList::anyAccountIsValid()
-{
- for(auto account:m_accounts)
- {
- if(account->accountStatus() != NotVerified)
- return true;
- }
- return false;
-}
diff --git a/libraries/logic/minecraft/auth/MojangAccountList.h b/libraries/logic/minecraft/auth/MojangAccountList.h
deleted file mode 100644
index c40fa6a3..00000000
--- a/libraries/logic/minecraft/auth/MojangAccountList.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "MojangAccount.h"
-
-#include <QObject>
-#include <QVariant>
-#include <QAbstractListModel>
-#include <QSharedPointer>
-
-#include "multimc_logic_export.h"
-
-/*!
- * \brief List of available Mojang accounts.
- * This should be loaded in the background by MultiMC on startup.
- *
- * This class also inherits from QAbstractListModel. Methods from that
- * class determine how this list shows up in a list view. Said methods
- * all have a default implementation, but they can be overridden by subclasses to
- * change the behavior of the list.
- */
-class MULTIMC_LOGIC_EXPORT MojangAccountList : public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum ModelRoles
- {
- PointerRole = 0x34B1CB48
- };
-
- enum VListColumns
- {
- // TODO: Add icon column.
-
- // First column - Active?
- ActiveColumn = 0,
-
- // Second column - Name
- NameColumn,
- };
-
- explicit MojangAccountList(QObject *parent = 0);
-
- //! Gets the account at the given index.
- virtual const MojangAccountPtr at(int i) const;
-
- //! Returns the number of accounts in the list.
- virtual int count() const;
-
- //////// List Model Functions ////////
- virtual QVariant data(const QModelIndex &index, int role) const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual int rowCount(const QModelIndex &parent) const;
- virtual int columnCount(const QModelIndex &parent) const;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
-
- /*!
- * Adds a the given Mojang account to the account list.
- */
- virtual void addAccount(const MojangAccountPtr account);
-
- /*!
- * Removes the mojang account with the given username from the account list.
- */
- virtual void removeAccount(const QString &username);
-
- /*!
- * Removes the account at the given QModelIndex.
- */
- virtual void removeAccount(QModelIndex index);
-
- /*!
- * \brief Finds an account by its username.
- * \param The username of the account to find.
- * \return A const pointer to the account with the given username. NULL if
- * one doesn't exist.
- */
- virtual MojangAccountPtr findAccount(const QString &username) const;
-
- /*!
- * Sets the default path to save the list file to.
- * If autosave is true, this list will automatically save to the given path whenever it changes.
- * THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately
- * after calling this function to ensure an autosaved change doesn't overwrite the list you intended
- * to load.
- */
- virtual void setListFilePath(QString path, bool autosave = false);
-
- /*!
- * \brief Loads the account list from the given file path.
- * If the given file is an empty string (default), will load from the default account list file.
- * \return True if successful, otherwise false.
- */
- virtual bool loadList(const QString &file = "");
-
- /*!
- * \brief Saves the account list to the given file.
- * If the given file is an empty string (default), will save from the default account list file.
- * \return True if successful, otherwise false.
- */
- virtual bool saveList(const QString &file = "");
-
- /*!
- * \brief Gets a pointer to the account that the user has selected as their "active" account.
- * Which account is active can be overridden on a per-instance basis, but this will return the one that
- * is set as active globally.
- * \return The currently active MojangAccount. If there isn't an active account, returns a null pointer.
- */
- virtual MojangAccountPtr activeAccount() const;
-
- /*!
- * Sets the given account as the current active account.
- * If the username given is an empty string, sets the active account to nothing.
- */
- virtual void setActiveAccount(const QString &username);
-
- /*!
- * Returns true if any of the account is at least Validated
- */
- bool anyAccountIsValid();
-
-signals:
- /*!
- * Signal emitted to indicate that the account list has changed.
- * This will also fire if the value of an element in the list changes (will be implemented
- * later).
- */
- void listChanged();
-
- /*!
- * Signal emitted to indicate that the active account has changed.
- */
- void activeAccountChanged();
-
-public
-slots:
- /**
- * This is called when one of the accounts changes and the list needs to be updated
- */
- void accountChanged();
-
-protected:
- /*!
- * Called whenever the list changes.
- * This emits the listChanged() signal and autosaves the list (if autosave is enabled).
- */
- void onListChanged();
-
- /*!
- * Called whenever the active account changes.
- * Emits the activeAccountChanged() signal and autosaves the list if enabled.
- */
- void onActiveChanged();
-
- QList<MojangAccountPtr> m_accounts;
-
- /*!
- * Account that is currently active.
- */
- MojangAccountPtr m_activeAccount;
-
- //! Path to the account list file. Empty string if there isn't one.
- QString m_listFilePath;
-
- /*!
- * If true, the account list will automatically save to the account list path when it changes.
- * Ignored if m_listFilePath is blank.
- */
- bool m_autosave = false;
-
-protected
-slots:
- /*!
- * Updates this list with the given list of accounts.
- * This is done by copying each account in the given list and inserting it
- * into this one.
- * We need to do this so that we can set the parents of the accounts are set to this
- * account list. This can't be done in the load task, because the accounts the load
- * task creates are on the load task's thread and Qt won't allow their parents
- * to be set to something created on another thread.
- * To get around that problem, we invoke this method on the GUI thread, which
- * then copies the accounts and sets their parents correctly.
- * \param accounts List of accounts whose parents should be set.
- */
- virtual void updateListData(QList<MojangAccountPtr> versions);
-};
diff --git a/libraries/logic/minecraft/auth/YggdrasilTask.cpp b/libraries/logic/minecraft/auth/YggdrasilTask.cpp
deleted file mode 100644
index c6971c9f..00000000
--- a/libraries/logic/minecraft/auth/YggdrasilTask.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Copyright 2013-2015 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 "YggdrasilTask.h"
-#include "MojangAccount.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-#include <QJsonDocument>
-#include <QNetworkReply>
-#include <QByteArray>
-
-#include <Env.h>
-
-#include <net/URLConstants.h>
-
-#include <QDebug>
-
-YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent)
- : Task(parent), m_account(account)
-{
- changeState(STATE_CREATED);
-}
-
-void YggdrasilTask::executeTask()
-{
- changeState(STATE_SENDING_REQUEST);
-
- // Get the content of the request we're going to send to the server.
- QJsonDocument doc(getRequestContent());
-
- auto worker = ENV.qnam();
- QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint());
- QNetworkRequest netRequest(reqUrl);
- netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- QByteArray requestData = doc.toJson();
- m_netReply = worker->post(netRequest, requestData);
- connect(m_netReply, &QNetworkReply::finished, this, &YggdrasilTask::processReply);
- connect(m_netReply, &QNetworkReply::uploadProgress, this, &YggdrasilTask::refreshTimers);
- connect(m_netReply, &QNetworkReply::downloadProgress, this, &YggdrasilTask::refreshTimers);
- connect(m_netReply, &QNetworkReply::sslErrors, this, &YggdrasilTask::sslErrors);
- timeout_keeper.setSingleShot(true);
- timeout_keeper.start(timeout_max);
- counter.setSingleShot(false);
- counter.start(time_step);
- progress(0, timeout_max);
- connect(&timeout_keeper, &QTimer::timeout, this, &YggdrasilTask::abortByTimeout);
- connect(&counter, &QTimer::timeout, this, &YggdrasilTask::heartbeat);
-}
-
-void YggdrasilTask::refreshTimers(qint64, qint64)
-{
- timeout_keeper.stop();
- timeout_keeper.start(timeout_max);
- progress(count = 0, timeout_max);
-}
-void YggdrasilTask::heartbeat()
-{
- count += time_step;
- progress(count, timeout_max);
-}
-
-bool YggdrasilTask::abort()
-{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = YggdrasilTask::BY_USER;
- m_netReply->abort();
- return true;
-}
-
-void YggdrasilTask::abortByTimeout()
-{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = YggdrasilTask::BY_TIMEOUT;
- m_netReply->abort();
-}
-
-void YggdrasilTask::sslErrors(QList<QSslError> errors)
-{
- int i = 1;
- for (auto error : errors)
- {
- qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString();
- auto cert = error.certificate();
- qCritical() << "Certificate in question:\n" << cert.toText();
- i++;
- }
-}
-
-void YggdrasilTask::processReply()
-{
- changeState(STATE_PROCESSING_RESPONSE);
-
- switch (m_netReply->error())
- {
- case QNetworkReply::NoError:
- break;
- case QNetworkReply::TimeoutError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation timed out."));
- return;
- case QNetworkReply::OperationCanceledError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
- return;
- case QNetworkReply::SslHandshakeFailedError:
- changeState(
- STATE_FAILED_SOFT,
- tr("<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>"
- "<ul>"
- "<li>You use Windows XP and need to <a "
- "href=\"http://www.microsoft.com/en-us/download/details.aspx?id=38918\">update "
- "your root certificates</a></li>"
- "<li>Some device on your network is interfering with SSL traffic. In that case, "
- "you have bigger worries than Minecraft not starting.</li>"
- "<li>Possibly something else. Check the MultiMC log file for details</li>"
- "</ul>"));
- return;
- // used for invalid credentials and similar errors. Fall through.
- case QNetworkReply::ContentOperationNotPermittedError:
- break;
- default:
- changeState(STATE_FAILED_SOFT,
- tr("Authentication operation failed due to a network error: %1 (%2)")
- .arg(m_netReply->errorString()).arg(m_netReply->error()));
- return;
- }
-
- // Try to parse the response regardless of the response code.
- // Sometimes the auth server will give more information and an error code.
- QJsonParseError jsonError;
- QByteArray replyData = m_netReply->readAll();
- QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError);
- // Check the response code.
- int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-
- if (responseCode == 200)
- {
- // If the response code was 200, then there shouldn't be an error. Make sure
- // anyways.
- // Also, sometimes an empty reply indicates success. If there was no data received,
- // pass an empty json object to the processResponse function.
- if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0)
- {
- processResponse(replyData.size() > 0 ? doc.object() : QJsonObject());
- return;
- }
- else
- {
- changeState(STATE_FAILED_SOFT, tr("Failed to parse authentication server response "
- "JSON response: %1 at offset %2.")
- .arg(jsonError.errorString())
- .arg(jsonError.offset));
- qCritical() << replyData;
- }
- return;
- }
-
- // If the response code was not 200, then Yggdrasil may have given us information
- // about the error.
- // If we can parse the response, then get information from it. Otherwise just say
- // there was an unknown error.
- if (jsonError.error == QJsonParseError::NoError)
- {
- // We were able to parse the server's response. Woo!
- // Call processError. If a subclass has overridden it then they'll handle their
- // stuff there.
- qDebug() << "The request failed, but the server gave us an error message. "
- "Processing error.";
- processError(doc.object());
- }
- else
- {
- // The server didn't say anything regarding the error. Give the user an unknown
- // error.
- qDebug()
- << "The request failed and the server gave no error message. Unknown error.";
- changeState(STATE_FAILED_SOFT,
- tr("An unknown error occurred when trying to communicate with the "
- "authentication server: %1").arg(m_netReply->errorString()));
- }
-}
-
-void YggdrasilTask::processError(QJsonObject responseData)
-{
- QJsonValue errorVal = responseData.value("error");
- QJsonValue errorMessageValue = responseData.value("errorMessage");
- QJsonValue causeVal = responseData.value("cause");
-
- if (errorVal.isString() && errorMessageValue.isString())
- {
- m_error = std::shared_ptr<Error>(new Error{
- errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("")});
- changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
- }
- else
- {
- // Error is not in standard format. Don't set m_error and return unknown error.
- changeState(STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred."));
- }
-}
-
-QString YggdrasilTask::getStateMessage() const
-{
- switch (m_state)
- {
- case STATE_CREATED:
- return "Waiting...";
- case STATE_SENDING_REQUEST:
- return tr("Sending request to auth servers...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Processing response from servers...");
- case STATE_SUCCEEDED:
- return tr("Authentication task succeeded.");
- case STATE_FAILED_SOFT:
- return tr("Failed to contact the authentication server.");
- case STATE_FAILED_HARD:
- return tr("Failed to authenticate.");
- default:
- return tr("...");
- }
-}
-
-void YggdrasilTask::changeState(YggdrasilTask::State newState, QString reason)
-{
- m_state = newState;
- setStatus(getStateMessage());
- if (newState == STATE_SUCCEEDED)
- {
- emitSucceeded();
- }
- else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT)
- {
- emitFailed(reason);
- }
-}
-
-YggdrasilTask::State YggdrasilTask::state()
-{
- return m_state;
-}
diff --git a/libraries/logic/minecraft/auth/YggdrasilTask.h b/libraries/logic/minecraft/auth/YggdrasilTask.h
deleted file mode 100644
index c84cfc06..00000000
--- a/libraries/logic/minecraft/auth/YggdrasilTask.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <tasks/Task.h>
-
-#include <QString>
-#include <QJsonObject>
-#include <QTimer>
-#include <qsslerror.h>
-
-#include "MojangAccount.h"
-
-class QNetworkReply;
-
-/**
- * A Yggdrasil task is a task that performs an operation on a given mojang account.
- */
-class YggdrasilTask : public Task
-{
- Q_OBJECT
-public:
- explicit YggdrasilTask(MojangAccount * account, QObject *parent = 0);
-
- /**
- * assign a session to this task. the session will be filled with required infomration
- * upon completion
- */
- void assignSession(AuthSessionPtr session)
- {
- m_session = session;
- }
-
- /// get the assigned session for filling with information.
- AuthSessionPtr getAssignedSession()
- {
- return m_session;
- }
-
- /**
- * Class describing a Yggdrasil error response.
- */
- struct Error
- {
- QString m_errorMessageShort;
- QString m_errorMessageVerbose;
- QString m_cause;
- };
-
- enum AbortedBy
- {
- BY_NOTHING,
- BY_USER,
- BY_TIMEOUT
- } m_aborted = BY_NOTHING;
-
- /**
- * Enum for describing the state of the current task.
- * Used by the getStateMessage function to determine what the status message should be.
- */
- enum State
- {
- STATE_CREATED,
- STATE_SENDING_REQUEST,
- STATE_PROCESSING_RESPONSE,
- STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated
- STATE_FAILED_HARD, //!< hard failure. auth is invalid
- STATE_SUCCEEDED
- } m_state = STATE_CREATED;
-
-protected:
-
- virtual void executeTask() override;
-
- /**
- * Gets the JSON object that will be sent to the authentication server.
- * Should be overridden by subclasses.
- */
- virtual QJsonObject getRequestContent() const = 0;
-
- /**
- * Gets the endpoint to POST to.
- * No leading slash.
- */
- virtual QString getEndpoint() const = 0;
-
- /**
- * Processes the response received from the server.
- * If an error occurred, this should emit a failed signal and return false.
- * If Yggdrasil gave an error response, it should call setError() first, and then return false.
- * Otherwise, it should return true.
- * Note: If the response from the server was blank, and the HTTP code was 200, this function is called with
- * an empty QJsonObject.
- */
- virtual void processResponse(QJsonObject responseData) = 0;
-
- /**
- * Processes an error response received from the server.
- * The default implementation will read data from Yggdrasil's standard error response format and set it as this task's Error.
- * \returns a QString error message that will be passed to emitFailed.
- */
- virtual void processError(QJsonObject responseData);
-
- /**
- * Returns the state message for the given state.
- * Used to set the status message for the task.
- * Should be overridden by subclasses that want to change messages for a given state.
- */
- virtual QString getStateMessage() const;
-
-protected
-slots:
- void processReply();
- void refreshTimers(qint64, qint64);
- void heartbeat();
- void sslErrors(QList<QSslError>);
-
- void changeState(State newState, QString reason=QString());
-public
-slots:
- virtual bool abort() override;
- void abortByTimeout();
- State state();
-protected:
- // FIXME: segfault disaster waiting to happen
- MojangAccount *m_account = nullptr;
- QNetworkReply *m_netReply = nullptr;
- std::shared_ptr<Error> m_error;
- QTimer timeout_keeper;
- QTimer counter;
- int count = 0; // num msec since time reset
-
- const int timeout_max = 30000;
- const int time_step = 50;
-
- AuthSessionPtr m_session;
-};
diff --git a/libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp b/libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp
deleted file mode 100644
index 8d136f0b..00000000
--- a/libraries/logic/minecraft/auth/flows/AuthenticateTask.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-
-/* Copyright 2013-2015 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 "AuthenticateTask.h"
-#include "../MojangAccount.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QVariant>
-
-#include <QDebug>
-#include <QUuid>
-
-AuthenticateTask::AuthenticateTask(MojangAccount * account, const QString &password,
- QObject *parent)
- : YggdrasilTask(account, parent), m_password(password)
-{
-}
-
-QJsonObject AuthenticateTask::getRequestContent() const
-{
- /*
- * {
- * "agent": { // optional
- * "name": "Minecraft", // So far this is the only encountered value
- * "version": 1 // This number might be increased
- * // by the vanilla client in the future
- * },
- * "username": "mojang account name", // Can be an email address or player name for
- // unmigrated accounts
- * "password": "mojang account password",
- * "clientToken": "client identifier" // optional
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
-
- {
- QJsonObject agent;
- // C++ makes string literals void* for some stupid reason, so we have to tell it
- // QString... Thanks Obama.
- agent.insert("name", QString("Minecraft"));
- agent.insert("version", 1);
- req.insert("agent", agent);
- }
-
- req.insert("username", m_account->username());
- req.insert("password", m_password);
- req.insert("requestUser", true);
-
- // If we already have a client token, give it to the server.
- // Otherwise, let the server give us one.
-
- if(m_account->m_clientToken.isEmpty())
- {
- auto uuid = QUuid::createUuid();
- auto uuidString = uuid.toString().remove('{').remove('-').remove('}');
- m_account->m_clientToken = uuidString;
- }
- req.insert("clientToken", m_account->m_clientToken);
-
- return req;
-}
-
-void AuthenticateTask::processResponse(QJsonObject responseData)
-{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- qDebug() << "Getting client token.";
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty())
- {
- // Fail if the server gave us an empty client token
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
- // Set the client token.
- m_account->m_clientToken = clientToken;
-
- // Now, we set the access token.
- qDebug() << "Getting access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty())
- {
- // Fail if the server didn't give us an access token.
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
- // Set the access token.
- m_account->m_accessToken = accessToken;
-
- // Now we load the list of available profiles.
- // Mojang hasn't yet implemented the profile system,
- // but we might as well support what's there so we
- // don't have trouble implementing it later.
- qDebug() << "Loading profile list.";
- QJsonArray availableProfiles = responseData.value("availableProfiles").toArray();
- QList<AccountProfile> loadedProfiles;
- for (auto iter : availableProfiles)
- {
- QJsonObject profile = iter.toObject();
- // Profiles are easy, we just need their ID and name.
- QString id = profile.value("id").toString("");
- QString name = profile.value("name").toString("");
- bool legacy = profile.value("legacy").toBool(false);
-
- if (id.isEmpty() || name.isEmpty())
- {
- // This should never happen, but we might as well
- // warn about it if it does so we can debug it easily.
- // You never know when Mojang might do something truly derpy.
- qWarning() << "Found entry in available profiles list with missing ID or name "
- "field. Ignoring it.";
- }
-
- // Now, add a new AccountProfile entry to the list.
- loadedProfiles.append({id, name, legacy});
- }
- // Put the list of profiles we loaded into the MojangAccount object.
- m_account->m_profiles = loadedProfiles;
-
- // Finally, we set the current profile to the correct value. This is pretty simple.
- // We do need to make sure that the current profile that the server gave us
- // is actually in the available profiles list.
- // If it isn't, we'll just fail horribly (*shouldn't* ever happen, but you never know).
- qDebug() << "Setting current profile.";
- QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
- QString currentProfileId = currentProfile.value("id").toString("");
- if (currentProfileId.isEmpty())
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify a currently selected profile. The account exists, but likely isn't premium."));
- return;
- }
- if (!m_account->setCurrentProfile(currentProfileId))
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server specified a selected profile that wasn't in the available profiles list."));
- return;
- }
-
- // this is what the vanilla launcher passes to the userProperties launch param
- if (responseData.contains("user"))
- {
- User u;
- auto obj = responseData.value("user").toObject();
- u.id = obj.value("id").toString();
- auto propArray = obj.value("properties").toArray();
- for (auto prop : propArray)
- {
- auto propTuple = prop.toObject();
- auto name = propTuple.value("name").toString();
- auto value = propTuple.value("value").toString();
- u.properties.insert(name, value);
- }
- m_account->m_user = u;
- }
-
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading authentication response.";
- changeState(STATE_SUCCEEDED);
-}
-
-QString AuthenticateTask::getEndpoint() const
-{
- return "authenticate";
-}
-
-QString AuthenticateTask::getStateMessage() const
-{
- switch (m_state)
- {
- case STATE_SENDING_REQUEST:
- return tr("Authenticating: Sending request...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Authenticating: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
-}
diff --git a/libraries/logic/minecraft/auth/flows/AuthenticateTask.h b/libraries/logic/minecraft/auth/flows/AuthenticateTask.h
deleted file mode 100644
index 398fab98..00000000
--- a/libraries/logic/minecraft/auth/flows/AuthenticateTask.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../YggdrasilTask.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-
-/**
- * The authenticate task takes a MojangAccount with no access token and password and attempts to
- * authenticate with Mojang's servers.
- * If successful, it will set the MojangAccount's access token.
- */
-class AuthenticateTask : public YggdrasilTask
-{
- Q_OBJECT
-public:
- AuthenticateTask(MojangAccount *account, const QString &password, QObject *parent = 0);
-
-protected:
- virtual QJsonObject getRequestContent() const override;
-
- virtual QString getEndpoint() const override;
-
- virtual void processResponse(QJsonObject responseData) override;
-
- virtual QString getStateMessage() const override;
-
-private:
- QString m_password;
-};
diff --git a/libraries/logic/minecraft/auth/flows/RefreshTask.cpp b/libraries/logic/minecraft/auth/flows/RefreshTask.cpp
deleted file mode 100644
index a0fb2e48..00000000
--- a/libraries/logic/minecraft/auth/flows/RefreshTask.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Copyright 2013-2015 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 "RefreshTask.h"
-#include "../MojangAccount.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QVariant>
-
-#include <QDebug>
-
-RefreshTask::RefreshTask(MojangAccount *account) : YggdrasilTask(account)
-{
-}
-
-QJsonObject RefreshTask::getRequestContent() const
-{
- /*
- * {
- * "clientToken": "client identifier"
- * "accessToken": "current access token to be refreshed"
- * "selectedProfile": // specifying this causes errors
- * {
- * "id": "profile ID"
- * "name": "profile name"
- * }
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
- req.insert("clientToken", m_account->m_clientToken);
- req.insert("accessToken", m_account->m_accessToken);
- /*
- {
- auto currentProfile = m_account->currentProfile();
- QJsonObject profile;
- profile.insert("id", currentProfile->id());
- profile.insert("name", currentProfile->name());
- req.insert("selectedProfile", profile);
- }
- */
- req.insert("requestUser", true);
-
- return req;
-}
-
-void RefreshTask::processResponse(QJsonObject responseData)
-{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
-
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty())
- {
- // Fail if the server gave us an empty client token
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
-
- // Now, we set the access token.
- qDebug() << "Getting new access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty())
- {
- // Fail if the server didn't give us an access token.
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
-
- // we validate that the server responded right. (our current profile = returned current
- // profile)
- QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
- QString currentProfileId = currentProfile.value("id").toString("");
- if (m_account->currentProfile()->id != currentProfileId)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify the same prefile as expected."));
- return;
- }
-
- // this is what the vanilla launcher passes to the userProperties launch param
- if (responseData.contains("user"))
- {
- User u;
- auto obj = responseData.value("user").toObject();
- u.id = obj.value("id").toString();
- auto propArray = obj.value("properties").toArray();
- for (auto prop : propArray)
- {
- auto propTuple = prop.toObject();
- auto name = propTuple.value("name").toString();
- auto value = propTuple.value("value").toString();
- u.properties.insert(name, value);
- }
- m_account->m_user = u;
- }
-
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading refresh response.";
- // Reset the access token.
- m_account->m_accessToken = accessToken;
- changeState(STATE_SUCCEEDED);
-}
-
-QString RefreshTask::getEndpoint() const
-{
- return "refresh";
-}
-
-QString RefreshTask::getStateMessage() const
-{
- switch (m_state)
- {
- case STATE_SENDING_REQUEST:
- return tr("Refreshing login token...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Refreshing login token: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
-}
diff --git a/libraries/logic/minecraft/auth/flows/RefreshTask.h b/libraries/logic/minecraft/auth/flows/RefreshTask.h
deleted file mode 100644
index 17714b4f..00000000
--- a/libraries/logic/minecraft/auth/flows/RefreshTask.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../YggdrasilTask.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-
-/**
- * The authenticate task takes a MojangAccount with a possibly timed-out access token
- * and attempts to authenticate with Mojang's servers.
- * If successful, it will set the new access token. The token is considered validated.
- */
-class RefreshTask : public YggdrasilTask
-{
- Q_OBJECT
-public:
- RefreshTask(MojangAccount * account);
-
-protected:
- virtual QJsonObject getRequestContent() const override;
-
- virtual QString getEndpoint() const override;
-
- virtual void processResponse(QJsonObject responseData) override;
-
- virtual QString getStateMessage() const override;
-};
-
diff --git a/libraries/logic/minecraft/auth/flows/ValidateTask.cpp b/libraries/logic/minecraft/auth/flows/ValidateTask.cpp
deleted file mode 100644
index 4deceb6a..00000000
--- a/libraries/logic/minecraft/auth/flows/ValidateTask.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* Copyright 2013-2015 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 "ValidateTask.h"
-#include "../MojangAccount.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QVariant>
-
-#include <QDebug>
-
-ValidateTask::ValidateTask(MojangAccount * account, QObject *parent)
- : YggdrasilTask(account, parent)
-{
-}
-
-QJsonObject ValidateTask::getRequestContent() const
-{
- QJsonObject req;
- req.insert("accessToken", m_account->m_accessToken);
- return req;
-}
-
-void ValidateTask::processResponse(QJsonObject responseData)
-{
- // Assume that if processError wasn't called, then the request was successful.
- changeState(YggdrasilTask::STATE_SUCCEEDED);
-}
-
-QString ValidateTask::getEndpoint() const
-{
- return "validate";
-}
-
-QString ValidateTask::getStateMessage() const
-{
- switch (m_state)
- {
- case YggdrasilTask::STATE_SENDING_REQUEST:
- return tr("Validating access token: Sending request...");
- case YggdrasilTask::STATE_PROCESSING_RESPONSE:
- return tr("Validating access token: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
-}
diff --git a/libraries/logic/minecraft/auth/flows/ValidateTask.h b/libraries/logic/minecraft/auth/flows/ValidateTask.h
deleted file mode 100644
index 77d628a0..00000000
--- a/libraries/logic/minecraft/auth/flows/ValidateTask.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright 2013-2015 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.
- */
-
-/*
- * :FIXME: DEAD CODE, DEAD CODE, DEAD CODE! :FIXME:
- */
-
-#pragma once
-
-#include "../YggdrasilTask.h"
-
-#include <QObject>
-#include <QString>
-#include <QJsonObject>
-
-/**
- * The validate task takes a MojangAccount and checks to make sure its access token is valid.
- */
-class ValidateTask : public YggdrasilTask
-{
- Q_OBJECT
-public:
- ValidateTask(MojangAccount *account, QObject *parent = 0);
-
-protected:
- virtual QJsonObject getRequestContent() const override;
-
- virtual QString getEndpoint() const override;
-
- virtual void processResponse(QJsonObject responseData) override;
-
- virtual QString getStateMessage() const override;
-
-private:
-};
diff --git a/libraries/logic/minecraft/forge/ForgeInstaller.cpp b/libraries/logic/minecraft/forge/ForgeInstaller.cpp
deleted file mode 100644
index 353328ab..00000000
--- a/libraries/logic/minecraft/forge/ForgeInstaller.cpp
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright 2013-2015 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 "ForgeInstaller.h"
-#include "ForgeVersionList.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/GradleSpecifier.h"
-#include "net/HttpMetaCache.h"
-#include "tasks/Task.h"
-#include "minecraft/onesix/OneSixInstance.h"
-#include <minecraft/onesix/OneSixVersionFormat.h>
-#include "minecraft/VersionFilterData.h"
-#include "minecraft/MinecraftVersion.h"
-#include "Env.h"
-#include "Exception.h"
-#include <FileSystem.h>
-
-#include <quazip.h>
-#include <quazipfile.h>
-#include <QStringList>
-#include <QRegularExpression>
-#include <QRegularExpressionMatch>
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QSaveFile>
-#include <QCryptographicHash>
-
-ForgeInstaller::ForgeInstaller() : BaseInstaller()
-{
-}
-
-void ForgeInstaller::prepare(const QString &filename, const QString &universalUrl)
-{
- VersionFilePtr newVersion;
- m_universal_url = universalUrl;
-
- QuaZip zip(filename);
- if (!zip.open(QuaZip::mdUnzip))
- return;
-
- QuaZipFile file(&zip);
-
- // read the install profile
- if (!zip.setCurrentFile("install_profile.json"))
- return;
-
- QJsonParseError jsonError;
- if (!file.open(QIODevice::ReadOnly))
- return;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError);
- file.close();
- if (jsonError.error != QJsonParseError::NoError)
- return;
-
- if (!jsonDoc.isObject())
- return;
-
- QJsonObject root = jsonDoc.object();
-
- auto installVal = root.value("install");
- auto versionInfoVal = root.value("versionInfo");
- if (!installVal.isObject() || !versionInfoVal.isObject())
- return;
-
- try
- {
- newVersion = OneSixVersionFormat::versionFileFromJson(QJsonDocument(versionInfoVal.toObject()), QString(), false);
- }
- catch(Exception &err)
- {
- qWarning() << "Forge: Fatal error while parsing version file:" << err.what();
- return;
- }
-
- for(auto problem: newVersion->getProblems())
- {
- qWarning() << "Forge: Problem found: " << problem.getDescription();
- }
- if(newVersion->getProblemSeverity() == ProblemSeverity::PROBLEM_ERROR)
- {
- qWarning() << "Forge: Errors found while parsing version file";
- return;
- }
-
- QJsonObject installObj = installVal.toObject();
- QString libraryName = installObj.value("path").toString();
- internalPath = installObj.value("filePath").toString();
- m_forgeVersionString = installObj.value("version").toString().remove("Forge", Qt::CaseInsensitive).trimmed();
-
- // where do we put the library? decode the mojang path
- GradleSpecifier lib(libraryName);
-
- auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.toPath());
- finalPath = "libraries/" + lib.toPath();
- if (!FS::ensureFilePathExists(finalPath))
- return;
-
- if (!zip.setCurrentFile(internalPath))
- return;
- if (!file.open(QIODevice::ReadOnly))
- return;
- {
- QByteArray data = file.readAll();
- // extract file
- QSaveFile extraction(finalPath);
- if (!extraction.open(QIODevice::WriteOnly))
- return;
- if (extraction.write(data) != data.size())
- return;
- if (!extraction.commit())
- return;
- QCryptographicHash md5sum(QCryptographicHash::Md5);
- md5sum.addData(data);
-
- cacheentry->setStale(false);
- cacheentry->setMD5Sum(md5sum.result().toHex().constData());
- ENV.metacache()->updateEntry(cacheentry);
- }
- file.close();
-
- m_forge_json = newVersion;
-}
-
-bool ForgeInstaller::add(OneSixInstance *to)
-{
- if (!BaseInstaller::add(to))
- {
- return false;
- }
-
- if (!m_forge_json)
- {
- return false;
- }
-
- // A blacklist
- QSet<QString> blacklist{"authlib", "realms"};
- QList<QString> xzlist{"org.scala-lang", "com.typesafe"};
-
- // get the minecraft version from the instance
- VersionFilePtr minecraft;
- auto minecraftPatch = to->getMinecraftProfile()->versionPatch("net.minecraft");
- if(minecraftPatch)
- {
- minecraft = std::dynamic_pointer_cast<VersionFile>(minecraftPatch);
- if(!minecraft)
- {
- auto mcWrap = std::dynamic_pointer_cast<MinecraftVersion>(minecraftPatch);
- if(mcWrap)
- {
- minecraft = mcWrap->getVersionFile();
- }
- }
- }
-
- // for each library in the version we are adding (except for the blacklisted)
- QMutableListIterator<LibraryPtr> iter(m_forge_json->libraries);
- while (iter.hasNext())
- {
- auto library = iter.next();
- QString libName = library->artifactId();
- QString libVersion = library->version();
- QString rawName = library->rawName();
-
- // ignore lwjgl libraries.
- if (g_VersionFilterData.lwjglWhitelist.contains(library->artifactPrefix()))
- {
- iter.remove();
- continue;
- }
- // ignore other blacklisted (realms, authlib)
- if (blacklist.contains(libName))
- {
- iter.remove();
- continue;
- }
- // if minecraft version was found, ignore everything that is already in the minecraft version
- if(minecraft)
- {
- bool found = false;
- for (auto & lib: minecraft->libraries)
- {
- if(library->artifactPrefix() == lib->artifactPrefix() && library->version() == lib->version())
- {
- found = true;
- break;
- }
- }
- if (found)
- continue;
- }
-
- // if this is the actual forge lib, set an absolute url for the download
- if (m_forge_version->type == ForgeVersion::Gradle)
- {
- if (libName == "forge")
- {
- library->setClassifier("universal");
- }
- else if (libName == "minecraftforge")
- {
- QString forgeCoord("net.minecraftforge:forge:%1:universal");
- // using insane form of the MC version...
- QString longVersion = m_forge_version->mcver + "-" + m_forge_version->jobbuildver;
- GradleSpecifier spec(forgeCoord.arg(longVersion));
- library->setRawName(spec);
- }
- }
- else
- {
- if (libName.contains("minecraftforge"))
- {
- library->setAbsoluteUrl(m_universal_url);
- }
- }
-
- // mark bad libraries based on the xzlist above
- for (auto entry : xzlist)
- {
- qDebug() << "Testing " << rawName << " : " << entry;
- if (rawName.startsWith(entry))
- {
- library->setHint("forge-pack-xz");
- break;
- }
- }
- }
- QString &args = m_forge_json->minecraftArguments;
- QStringList tweakers;
- {
- QRegularExpression expression("--tweakClass ([a-zA-Z0-9\\.]*)");
- QRegularExpressionMatch match = expression.match(args);
- while (match.hasMatch())
- {
- tweakers.append(match.captured(1));
- args.remove(match.capturedStart(), match.capturedLength());
- match = expression.match(args);
- }
- if(tweakers.size())
- {
- args.operator=(args.trimmed());
- m_forge_json->addTweakers = tweakers;
- }
- }
- if(minecraft && args == minecraft->minecraftArguments)
- {
- args.clear();
- }
-
- m_forge_json->name = "Forge";
- m_forge_json->fileId = id();
- m_forge_json->version = m_forgeVersionString;
- m_forge_json->dependsOnMinecraftVersion = to->intendedVersionId();
- m_forge_json->order = 5;
-
- // reset some things we do not want to be passed along.
- m_forge_json->m_releaseTime = QDateTime();
- m_forge_json->m_updateTime = QDateTime();
- m_forge_json->minimumLauncherVersion = -1;
- m_forge_json->type.clear();
- m_forge_json->minecraftArguments.clear();
- m_forge_json->minecraftVersion.clear();
-
- QSaveFile file(filename(to->instanceRoot()));
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(m_forge_json, true).toJson());
- file.commit();
-
- return true;
-}
-
-bool ForgeInstaller::addLegacy(OneSixInstance *to)
-{
- if (!BaseInstaller::add(to))
- {
- return false;
- }
- auto entry = ENV.metacache()->resolveEntry("minecraftforge", m_forge_version->filename());
- finalPath = FS::PathCombine(to->jarModsDir(), m_forge_version->filename());
- if (!FS::ensureFilePathExists(finalPath))
- {
- return false;
- }
- if (!QFile::copy(entry->getFullPath(), finalPath))
- {
- return false;
- }
- QJsonObject obj;
- obj.insert("order", 5);
- {
- QJsonArray jarmodsPlus;
- {
- QJsonObject libObj;
- libObj.insert("name", m_forge_version->universal_filename);
- jarmodsPlus.append(libObj);
- }
- obj.insert("+jarMods", jarmodsPlus);
- }
-
- obj.insert("name", QString("Forge"));
- obj.insert("fileId", id());
- obj.insert("version", m_forge_version->jobbuildver);
- obj.insert("mcVersion", to->intendedVersionId());
- if (g_VersionFilterData.fmlLibsMapping.contains(m_forge_version->mcver))
- {
- QJsonArray traitsPlus;
- traitsPlus.append(QString("legacyFML"));
- obj.insert("+traits", traitsPlus);
- }
- auto fullversion = to->getMinecraftProfile();
- fullversion->remove("net.minecraftforge");
-
- QFile file(filename(to->instanceRoot()));
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(QJsonDocument(obj).toJson());
- file.close();
- return true;
-}
-
-class ForgeInstallTask : public Task
-{
- Q_OBJECT
-public:
- ForgeInstallTask(ForgeInstaller *installer, OneSixInstance *instance,
- BaseVersionPtr version, QObject *parent = 0)
- : Task(parent), m_installer(installer), m_instance(instance), m_version(version)
- {
- }
-
-protected:
- void executeTask() override
- {
- setStatus(tr("Installing Forge..."));
- ForgeVersionPtr forgeVersion = std::dynamic_pointer_cast<ForgeVersion>(m_version);
- if (!forgeVersion)
- {
- emitFailed(tr("Unknown error occured"));
- return;
- }
- prepare(forgeVersion);
- }
- void prepare(ForgeVersionPtr forgeVersion)
- {
- auto entry = ENV.metacache()->resolveEntry("minecraftforge", forgeVersion->filename());
- auto installFunction = [this, entry, forgeVersion]()
- {
- if (!install(entry, forgeVersion))
- {
- qCritical() << "Failure installing Forge";
- emitFailed(tr("Failure to install Forge"));
- }
- else
- {
- reload();
- }
- };
-
- /*
- * HACK IF the local non-stale file is too small, mark is as stale
- *
- * This fixes some problems with bad files acquired because of unhandled HTTP redirects
- * in old versions of MultiMC.
- */
- if (!entry->isStale())
- {
- QFileInfo localFile(entry->getFullPath());
- if (localFile.size() <= 0x4000)
- {
- entry->setStale(true);
- }
- }
-
- if (entry->isStale())
- {
- NetJob *fjob = new NetJob("Forge download");
- fjob->addNetAction(CacheDownload::make(forgeVersion->url(), entry));
- connect(fjob, &NetJob::progress, this, &Task::setProgress);
- connect(fjob, &NetJob::status, this, &Task::setStatus);
- connect(fjob, &NetJob::failed, [this](QString reason)
- { emitFailed(tr("Failure to download Forge:\n%1").arg(reason)); });
- connect(fjob, &NetJob::succeeded, installFunction);
- fjob->start();
- }
- else
- {
- installFunction();
- }
- }
- bool install(const std::shared_ptr<MetaEntry> &entry, const ForgeVersionPtr &forgeVersion)
- {
- if (forgeVersion->usesInstaller())
- {
- QString forgePath = entry->getFullPath();
- m_installer->prepare(forgePath, forgeVersion->universal_url);
- return m_installer->add(m_instance);
- }
- else
- return m_installer->addLegacy(m_instance);
- }
- void reload()
- {
- try
- {
- m_instance->reloadProfile();
- emitSucceeded();
- }
- catch (Exception &e)
- {
- emitFailed(e.cause());
- }
- catch (...)
- {
- emitFailed(tr("Failed to load the version description file for reasons unknown."));
- }
- }
-
-private:
- ForgeInstaller *m_installer;
- OneSixInstance *m_instance;
- BaseVersionPtr m_version;
-};
-
-Task *ForgeInstaller::createInstallTask(OneSixInstance *instance,
- BaseVersionPtr version, QObject *parent)
-{
- if (!version)
- {
- return nullptr;
- }
- m_forge_version = std::dynamic_pointer_cast<ForgeVersion>(version);
- return new ForgeInstallTask(this, instance, version, parent);
-}
-
-#include "ForgeInstaller.moc"
diff --git a/libraries/logic/minecraft/forge/ForgeInstaller.h b/libraries/logic/minecraft/forge/ForgeInstaller.h
deleted file mode 100644
index 499a6fb3..00000000
--- a/libraries/logic/minecraft/forge/ForgeInstaller.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BaseInstaller.h"
-
-#include <QString>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class VersionFile;
-class ForgeInstallTask;
-struct ForgeVersion;
-
-class MULTIMC_LOGIC_EXPORT ForgeInstaller : public BaseInstaller
-{
- friend class ForgeInstallTask;
-public:
- ForgeInstaller();
- virtual ~ForgeInstaller(){}
- virtual Task *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
- virtual QString id() const override { return "net.minecraftforge"; }
-
-protected:
- void prepare(const QString &filename, const QString &universalUrl);
- bool add(OneSixInstance *to) override;
- bool addLegacy(OneSixInstance *to);
-
-private:
- // the parsed version json, read from the installer
- std::shared_ptr<VersionFile> m_forge_json;
- // the actual forge version
- std::shared_ptr<ForgeVersion> m_forge_version;
- QString internalPath;
- QString finalPath;
- QString m_forgeVersionString;
- QString m_universal_url;
-};
diff --git a/libraries/logic/minecraft/forge/ForgeVersion.cpp b/libraries/logic/minecraft/forge/ForgeVersion.cpp
deleted file mode 100644
index b859a28c..00000000
--- a/libraries/logic/minecraft/forge/ForgeVersion.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "ForgeVersion.h"
-#include "minecraft/VersionFilterData.h"
-#include <QObject>
-
-QString ForgeVersion::name()
-{
- return "Forge " + jobbuildver;
-}
-
-QString ForgeVersion::descriptor()
-{
- return universal_filename;
-}
-
-QString ForgeVersion::typeString() const
-{
- if (is_recommended)
- return QObject::tr("Recommended");
- return QString();
-}
-
-bool ForgeVersion::operator<(BaseVersion &a)
-{
- ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a);
- if (!pa)
- return true;
- return m_buildnr < pa->m_buildnr;
-}
-
-bool ForgeVersion::operator>(BaseVersion &a)
-{
- ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a);
- if (!pa)
- return false;
- return m_buildnr > pa->m_buildnr;
-}
-
-bool ForgeVersion::usesInstaller()
-{
- if(installer_url.isEmpty())
- return false;
- if(g_VersionFilterData.forgeInstallerBlacklist.contains(mcver))
- return false;
- return true;
-}
-
-QString ForgeVersion::filename()
-{
- return usesInstaller() ? installer_filename : universal_filename;
-}
-
-QString ForgeVersion::url()
-{
- return usesInstaller() ? installer_url : universal_url;
-}
diff --git a/libraries/logic/minecraft/forge/ForgeVersion.h b/libraries/logic/minecraft/forge/ForgeVersion.h
deleted file mode 100644
index e77d32f1..00000000
--- a/libraries/logic/minecraft/forge/ForgeVersion.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-#include <QString>
-#include <memory>
-#include "BaseVersion.h"
-
-struct ForgeVersion;
-typedef std::shared_ptr<ForgeVersion> ForgeVersionPtr;
-
-struct ForgeVersion : public BaseVersion
-{
- virtual QString descriptor() override;
- virtual QString name() override;
- virtual QString typeString() const override;
- virtual bool operator<(BaseVersion &a) override;
- virtual bool operator>(BaseVersion &a) override;
-
- QString filename();
- QString url();
-
- enum
- {
- Invalid,
- Legacy,
- Gradle
- } type = Invalid;
-
- bool usesInstaller();
-
- int m_buildnr = 0;
- QString branch;
- QString universal_url;
- QString changelog_url;
- QString installer_url;
- QString jobbuildver;
- QString mcver;
- QString mcver_sane;
- QString universal_filename;
- QString installer_filename;
- bool is_recommended = false;
-};
-
-Q_DECLARE_METATYPE(ForgeVersionPtr)
diff --git a/libraries/logic/minecraft/forge/ForgeVersionList.cpp b/libraries/logic/minecraft/forge/ForgeVersionList.cpp
deleted file mode 100644
index de185e5f..00000000
--- a/libraries/logic/minecraft/forge/ForgeVersionList.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/* Copyright 2013-2015 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 "ForgeVersionList.h"
-#include "ForgeVersion.h"
-
-#include "net/NetJob.h"
-#include "net/URLConstants.h"
-#include "Env.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include <QDebug>
-
-ForgeVersionList::ForgeVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *ForgeVersionList::getLoadTask()
-{
- return new ForgeListLoadTask(this);
-}
-
-bool ForgeVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr ForgeVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int ForgeVersionList::count() const
-{
- return m_vlist.count();
-}
-
-int ForgeVersionList::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant ForgeVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<ForgeVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case ParentGameVersionRole:
- return version->mcver_sane;
-
- case RecommendedRole:
- return version->is_recommended;
-
- case BranchRole:
- return version->branch;
-
- default:
- return QVariant();
- }
-}
-
-BaseVersionList::RoleList ForgeVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole, RecommendedRole, BranchRole};
-}
-
-BaseVersionPtr ForgeVersionList::getLatestStable() const
-{
- return BaseVersionPtr();
-}
-
-void ForgeVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- endResetModel();
- // NOW SORT!!
- // sort();
-}
-
-void ForgeVersionList::sortVersions()
-{
- // NO-OP for now
-}
-
-ForgeListLoadTask::ForgeListLoadTask(ForgeVersionList *vlist) : Task()
-{
- m_list = vlist;
-}
-
-void ForgeListLoadTask::executeTask()
-{
- setStatus(tr("Fetching Forge version lists..."));
- auto job = new NetJob("Version index");
- // we do not care if the version is stale or not.
- auto forgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "list.json");
- auto gradleForgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "json");
-
- // verify by poking the server.
- forgeListEntry->setStale(true);
- gradleForgeListEntry->setStale(true);
-
- job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::FORGE_LEGACY_URL),
- forgeListEntry));
- job->addNetAction(gradleListDownload = CacheDownload::make(
- QUrl(URLConstants::FORGE_GRADLE_URL), gradleForgeListEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
- connect(gradleListDownload.get(), SIGNAL(failed(int)), SLOT(gradleListFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-bool ForgeListLoadTask::abort()
-{
- return listJob->abort();
-}
-
-bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out)
-{
- QByteArray data;
- {
- auto dlJob = listDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("builds").isArray())
- {
- emitFailed(
- "Error parsing version list JSON: version list object is missing 'builds' array");
- return false;
- }
- QJsonArray builds = root.value("builds").toArray();
-
- for (int i = 0; i < builds.count(); i++)
- {
- // Load the version info.
- if (!builds[i].isObject())
- {
- // FIXME: log this somewhere
- continue;
- }
- QJsonObject obj = builds[i].toObject();
- int build_nr = obj.value("build").toDouble(0);
- if (!build_nr)
- continue;
- QJsonArray files = obj.value("files").toArray();
- QString url, jobbuildver, mcver, buildtype, universal_filename;
- QString changelog_url, installer_url;
- QString installer_filename;
- bool valid = false;
- for (int j = 0; j < files.count(); j++)
- {
- if (!files[j].isObject())
- {
- continue;
- }
- QJsonObject file = files[j].toObject();
- buildtype = file.value("buildtype").toString();
- if ((buildtype == "client" || buildtype == "universal") && !valid)
- {
- mcver = file.value("mcver").toString();
- url = file.value("url").toString();
- jobbuildver = file.value("jobbuildver").toString();
- int lastSlash = url.lastIndexOf('/');
- universal_filename = url.mid(lastSlash + 1);
- valid = true;
- }
- else if (buildtype == "changelog")
- {
- QString ext = file.value("ext").toString();
- if (ext.isEmpty())
- {
- continue;
- }
- changelog_url = file.value("url").toString();
- }
- else if (buildtype == "installer")
- {
- installer_url = file.value("url").toString();
- int lastSlash = installer_url.lastIndexOf('/');
- installer_filename = installer_url.mid(lastSlash + 1);
- }
- }
- if (valid)
- {
- // Now, we construct the version object and add it to the list.
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->universal_url = url;
- fVersion->changelog_url = changelog_url;
- fVersion->installer_url = installer_url;
- fVersion->jobbuildver = jobbuildver;
- fVersion->mcver = fVersion->mcver_sane = mcver;
- fVersion->installer_filename = installer_filename;
- fVersion->universal_filename = universal_filename;
- fVersion->m_buildnr = build_nr;
- fVersion->type = ForgeVersion::Legacy;
- out.append(fVersion);
- }
- }
-
- return true;
-}
-
-bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out)
-{
- QMap<int, std::shared_ptr<ForgeVersion>> lookup;
- QByteArray data;
- {
- auto dlJob = gradleListDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- return false;
- }
- data = listFile.readAll();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing gradle version list JSON:" + jsonError.errorString());
- return false;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing gradle version list JSON: JSON root is not an object");
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // we probably could hard code these, but it might still be worth doing it this way
- const QString webpath = root.value("webpath").toString();
- const QString artifact = root.value("artifact").toString();
-
- QJsonObject numbers = root.value("number").toObject();
- for (auto it = numbers.begin(); it != numbers.end(); ++it)
- {
- QJsonObject number = it.value().toObject();
- std::shared_ptr<ForgeVersion> fVersion(new ForgeVersion());
- fVersion->m_buildnr = number.value("build").toDouble();
- if(fVersion->m_buildnr >= 953 && fVersion->m_buildnr <= 965)
- {
- qDebug() << fVersion->m_buildnr;
- }
- fVersion->jobbuildver = number.value("version").toString();
- fVersion->branch = number.value("branch").toString("");
- fVersion->mcver = number.value("mcversion").toString();
- fVersion->universal_filename = "";
- fVersion->installer_filename = "";
- // HACK: here, we fix the minecraft version used by forge.
- // HACK: this will inevitably break (later)
- // FIXME: replace with a dictionary
- fVersion->mcver_sane = fVersion->mcver;
- fVersion->mcver_sane.replace("_pre", "-pre");
-
- QString universal_filename, installer_filename;
- QJsonArray files = number.value("files").toArray();
- for (auto fIt = files.begin(); fIt != files.end(); ++fIt)
- {
- // TODO with gradle we also get checksums, use them
- QJsonArray file = (*fIt).toArray();
- if (file.size() < 3)
- {
- continue;
- }
-
- QString extension = file.at(0).toString();
- QString part = file.at(1).toString();
- QString checksum = file.at(2).toString();
-
- // insane form of mcver is used here
- QString longVersion = fVersion->mcver + "-" + fVersion->jobbuildver;
- if (!fVersion->branch.isEmpty())
- {
- longVersion = longVersion + "-" + fVersion->branch;
- }
- QString filename = artifact + "-" + longVersion + "-" + part + "." + extension;
-
- QString url = QString("%1/%2/%3")
- .arg(webpath)
- .arg(longVersion)
- .arg(filename);
-
- if (part == "installer")
- {
- fVersion->installer_url = url;
- installer_filename = filename;
- }
- else if (part == "universal")
- {
- fVersion->universal_url = url;
- universal_filename = filename;
- }
- else if (part == "changelog")
- {
- fVersion->changelog_url = url;
- }
- }
- if (fVersion->installer_url.isEmpty() && fVersion->universal_url.isEmpty())
- {
- continue;
- }
- fVersion->universal_filename = universal_filename;
- fVersion->installer_filename = installer_filename;
- fVersion->type = ForgeVersion::Gradle;
- out.append(fVersion);
- lookup[fVersion->m_buildnr] = fVersion;
- }
- QJsonObject promos = root.value("promos").toObject();
- for (auto it = promos.begin(); it != promos.end(); ++it)
- {
- QString key = it.key();
- int build = it.value().toInt();
- QRegularExpression regexp("^(?<mcversion>[0-9]+(.[0-9]+)*)-(?<label>[a-z]+)$");
- auto match = regexp.match(key);
- if(!match.hasMatch())
- {
- qDebug() << key << "doesn't match." << "build" << build;
- continue;
- }
-
- QString label = match.captured("label");
- if(label != "recommended")
- {
- continue;
- }
- QString mcversion = match.captured("mcversion");
- qDebug() << "Forge build" << build << "is the" << label << "for Minecraft" << mcversion << QString("<%1>").arg(key);
- lookup[build]->is_recommended = true;
- }
- return true;
-}
-
-void ForgeListLoadTask::listDownloaded()
-{
- QList<BaseVersionPtr> list;
- bool ret = true;
- if (!parseForgeList(list))
- {
- ret = false;
- }
- if (!parseForgeGradleList(list))
- {
- ret = false;
- }
-
- if (!ret)
- {
- return;
- }
- std::sort(list.begin(), list.end(), [](const BaseVersionPtr & l, const BaseVersionPtr & r)
- { return (*l > *r); });
-
- m_list->updateListData(list);
-
- emitSucceeded();
- return;
-}
-
-void ForgeListLoadTask::listFailed()
-{
- auto &reply = listDownload->m_reply;
- if (reply)
- {
- qCritical() << "Getting forge version list failed: " << reply->errorString();
- }
- else
- {
- qCritical() << "Getting forge version list failed for reasons unknown.";
- }
-}
-
-void ForgeListLoadTask::gradleListFailed()
-{
- auto &reply = gradleListDownload->m_reply;
- if (reply)
- {
- qCritical() << "Getting forge version list failed: " << reply->errorString();
- }
- else
- {
- qCritical() << "Getting forge version list failed for reasons unknown.";
- }
-}
diff --git a/libraries/logic/minecraft/forge/ForgeVersionList.h b/libraries/logic/minecraft/forge/ForgeVersionList.h
deleted file mode 100644
index 62c08b2a..00000000
--- a/libraries/logic/minecraft/forge/ForgeVersionList.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "ForgeVersion.h"
-
-#include <QObject>
-#include <QAbstractListModel>
-#include <QUrl>
-#include <QNetworkReply>
-
-#include "BaseVersionList.h"
-#include "tasks/Task.h"
-#include "net/NetJob.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT ForgeVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- friend class ForgeListLoadTask;
-
- explicit ForgeVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask() override;
- virtual bool isLoaded() override;
- virtual const BaseVersionPtr at(int i) const override;
- virtual int count() const override;
- virtual void sortVersions() override;
-
- virtual BaseVersionPtr getLatestStable() const override;
-
- ForgeVersionPtr findVersionByVersionNr(QString version);
-
- virtual QVariant data(const QModelIndex &index, int role) const override;
- virtual RoleList providesRoles() const override;
-
- virtual int columnCount(const QModelIndex &parent) const override;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions) override;
-};
-
-class ForgeListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit ForgeListLoadTask(ForgeVersionList *vlist);
-
- virtual void executeTask();
- virtual bool abort();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
- void gradleListFailed();
-
-protected:
- NetJobPtr listJob;
- ForgeVersionList *m_list;
-
- CacheDownloadPtr listDownload;
- CacheDownloadPtr gradleListDownload;
-
-private:
- bool parseForgeList(QList<BaseVersionPtr> &out);
- bool parseForgeGradleList(QList<BaseVersionPtr> &out);
-};
diff --git a/libraries/logic/minecraft/forge/ForgeXzDownload.cpp b/libraries/logic/minecraft/forge/ForgeXzDownload.cpp
deleted file mode 100644
index adf96552..00000000
--- a/libraries/logic/minecraft/forge/ForgeXzDownload.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/* Copyright 2013-2015 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 "Env.h"
-#include "ForgeXzDownload.h"
-#include <FileSystem.h>
-
-#include <QCryptographicHash>
-#include <QFileInfo>
-#include <QDateTime>
-#include <QDir>
-#include <QDebug>
-
-ForgeXzDownload::ForgeXzDownload(QString relative_path, MetaEntryPtr entry) : NetAction()
-{
- m_entry = entry;
- m_target_path = entry->getFullPath();
- m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX");
- m_status = Job_NotStarted;
- m_url_path = relative_path;
- m_url = "http://files.minecraftforge.net/maven/" + m_url_path + ".pack.xz";
-}
-
-void ForgeXzDownload::start()
-{
- m_status = Job_InProgress;
- if (!m_entry->isStale())
- {
- m_status = Job_Finished;
- emit succeeded(m_index_within_job);
- return;
- }
- // can we actually create the real, final file?
- if (!FS::ensureFilePathExists(m_target_path))
- {
- m_status = Job_Failed;
- emit failed(m_index_within_job);
- return;
- }
-
- qDebug() << "Downloading " << m_url.toString();
- QNetworkRequest request(m_url);
- request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->get(request);
-
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
- SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
-}
-
-void ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
-
-void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error)
-{
- // error happened during download.
- // TODO: log the reason why
- m_status = Job_Failed;
-}
-
-void ForgeXzDownload::failAndTryNextMirror()
-{
- m_status = Job_Failed;
- emit failed(m_index_within_job);
-}
-
-void ForgeXzDownload::downloadFinished()
-{
- // if the download succeeded
- if (m_status != Job_Failed)
- {
- // nothing went wrong...
- m_status = Job_Finished;
- if (m_pack200_xz_file.isOpen())
- {
- // we actually downloaded something! process and isntall it
- decompressAndInstall();
- return;
- }
- else
- {
- // something bad happened -- on the local machine!
- m_status = Job_Failed;
- m_pack200_xz_file.remove();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- }
- // else the download failed
- else
- {
- m_status = Job_Failed;
- m_pack200_xz_file.close();
- m_pack200_xz_file.remove();
- m_reply.reset();
- failAndTryNextMirror();
- return;
- }
-}
-
-void ForgeXzDownload::downloadReadyRead()
-{
-
- if (!m_pack200_xz_file.isOpen())
- {
- if (!m_pack200_xz_file.open())
- {
- /*
- * Can't open the file... the job failed
- */
- m_reply->abort();
- emit failed(m_index_within_job);
- return;
- }
- }
- m_pack200_xz_file.write(m_reply->readAll());
-}
-
-#include "xz.h"
-#include "unpack200.h"
-#include <stdexcept>
-#include <unistd.h>
-
-const size_t buffer_size = 8196;
-
-void ForgeXzDownload::decompressAndInstall()
-{
- // rewind the downloaded temp file
- m_pack200_xz_file.seek(0);
- // de-xz'd file
- QTemporaryFile pack200_file("./dl_temp.XXXXXX");
- pack200_file.open();
-
- bool xz_success = false;
- // first, de-xz
- {
- uint8_t in[buffer_size];
- uint8_t out[buffer_size];
- struct xz_buf b;
- struct xz_dec *s;
- enum xz_ret ret;
- xz_crc32_init();
- xz_crc64_init();
- s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
- if (s == nullptr)
- {
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
- b.in = in;
- b.in_pos = 0;
- b.in_size = 0;
- b.out = out;
- b.out_pos = 0;
- b.out_size = buffer_size;
- while (!xz_success)
- {
- if (b.in_pos == b.in_size)
- {
- b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in));
- b.in_pos = 0;
- }
-
- ret = xz_dec_run(s, &b);
-
- if (b.out_pos == sizeof(out))
- {
- if (pack200_file.write((char *)out, b.out_pos) != b.out_pos)
- {
- // msg = "Write error\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
-
- b.out_pos = 0;
- }
-
- if (ret == XZ_OK)
- continue;
-
- if (ret == XZ_UNSUPPORTED_CHECK)
- {
- // unsupported check. this is OK, but we should log this
- continue;
- }
-
- if (pack200_file.write((char *)out, b.out_pos) != b.out_pos)
- {
- // write error
- pack200_file.close();
- xz_dec_end(s);
- return;
- }
-
- switch (ret)
- {
- case XZ_STREAM_END:
- xz_dec_end(s);
- xz_success = true;
- break;
-
- case XZ_MEM_ERROR:
- qCritical() << "Memory allocation failed\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_MEMLIMIT_ERROR:
- qCritical() << "Memory usage limit reached\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_FORMAT_ERROR:
- qCritical() << "Not a .xz file\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_OPTIONS_ERROR:
- qCritical() << "Unsupported options in the .xz headers\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_DATA_ERROR:
- case XZ_BUF_ERROR:
- qCritical() << "File is corrupt\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- default:
- qCritical() << "Bug!\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
- }
- }
- m_pack200_xz_file.remove();
-
- // revert pack200
- pack200_file.seek(0);
- int handle_in = pack200_file.handle();
- // FIXME: dispose of file handles, pointers and the like. Ideally wrap in objects.
- if(handle_in == -1)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_in_dup = dup (handle_in);
- if(handle_in_dup == -1)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- FILE *file_in = fdopen (handle_in_dup, "rb");
- if(!file_in)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- QFile qfile_out(m_target_path);
- if(!qfile_out.open(QIODevice::WriteOnly))
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_out = qfile_out.handle();
- if(handle_out == -1)
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_out_dup = dup (handle_out);
- if(handle_out_dup == -1)
- {
- qCritical() << "Error reopening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- FILE *file_out = fdopen (handle_out_dup, "wb");
- if(!file_out)
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- try
- {
- // NOTE: this takes ownership of both FILE pointers. That's why we duplicate them above.
- unpack_200(file_in, file_out);
- }
- catch (std::runtime_error &err)
- {
- m_status = Job_Failed;
- qCritical() << "Error unpacking " << pack200_file.fileName() << " : " << err.what();
- QFile f(m_target_path);
- if (f.exists())
- f.remove();
- failAndTryNextMirror();
- return;
- }
- pack200_file.remove();
-
- QFile jar_file(m_target_path);
-
- if (!jar_file.open(QIODevice::ReadOnly))
- {
- jar_file.remove();
- failAndTryNextMirror();
- return;
- }
- auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5);
- m_entry->setMD5Sum(hash.toHex().constData());
- jar_file.close();
-
- QFileInfo output_file_info(m_target_path);
- m_entry->setETag(m_reply->rawHeader("ETag").constData());
- m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
- m_entry->setStale(false);
- ENV.metacache()->updateEntry(m_entry);
-
- m_reply.reset();
- emit succeeded(m_index_within_job);
-}
diff --git a/libraries/logic/minecraft/forge/ForgeXzDownload.h b/libraries/logic/minecraft/forge/ForgeXzDownload.h
deleted file mode 100644
index 67524405..00000000
--- a/libraries/logic/minecraft/forge/ForgeXzDownload.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "net/NetAction.h"
-#include "net/HttpMetaCache.h"
-#include <QFile>
-#include <QTemporaryFile>
-
-typedef std::shared_ptr<class ForgeXzDownload> ForgeXzDownloadPtr;
-
-class ForgeXzDownload : public NetAction
-{
- Q_OBJECT
-public:
- MetaEntryPtr m_entry;
- /// if saving to file, use the one specified in this string
- QString m_target_path;
- /// this is the output file, if any
- QTemporaryFile m_pack200_xz_file;
- /// path relative to the mirror base
- QString m_url_path;
-
-public:
- explicit ForgeXzDownload(QString relative_path, MetaEntryPtr entry);
- static ForgeXzDownloadPtr make(QString relative_path, MetaEntryPtr entry)
- {
- return ForgeXzDownloadPtr(new ForgeXzDownload(relative_path, entry));
- }
- virtual ~ForgeXzDownload(){};
-
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead();
-
-public
-slots:
- virtual void start();
-
-private:
- void decompressAndInstall();
- void failAndTryNextMirror();
-};
diff --git a/libraries/logic/minecraft/forge/LegacyForge.cpp b/libraries/logic/minecraft/forge/LegacyForge.cpp
deleted file mode 100644
index aa2c8063..00000000
--- a/libraries/logic/minecraft/forge/LegacyForge.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright 2013-2015 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 "LegacyForge.h"
-
-MinecraftForge::MinecraftForge(const QString &file) : Mod(file)
-{
-}
-
-bool MinecraftForge::FixVersionIfNeeded(QString newVersion)
-{/*
- wxString reportedVersion = GetModVersion();
- if(reportedVersion == "..." || reportedVersion.empty())
- {
- std::auto_ptr<wxFFileInputStream> in(new wxFFileInputStream("forge.zip"));
- wxTempFileOutputStream out("forge.zip");
- wxTextOutputStream textout(out);
- wxZipInputStream inzip(*in);
- wxZipOutputStream outzip(out);
- std::auto_ptr<wxZipEntry> entry;
- // preserve metadata
- outzip.CopyArchiveMetaData(inzip);
- // copy all entries
- while (entry.reset(inzip.GetNextEntry()), entry.get() != NULL)
- if (!outzip.CopyEntry(entry.release(), inzip))
- return false;
- // release last entry
- in.reset();
- outzip.PutNextEntry("forgeversion.properties");
-
- wxStringTokenizer tokenizer(newVersion,".");
- wxString verFile;
- verFile << wxString("forge.major.number=") << tokenizer.GetNextToken() << "\n";
- verFile << wxString("forge.minor.number=") << tokenizer.GetNextToken() << "\n";
- verFile << wxString("forge.revision.number=") << tokenizer.GetNextToken() << "\n";
- verFile << wxString("forge.build.number=") << tokenizer.GetNextToken() << "\n";
- auto buf = verFile.ToUTF8();
- outzip.Write(buf.data(), buf.length());
- // check if we succeeded
- return inzip.Eof() && outzip.Close() && out.Commit();
- }
- */
- return true;
-}
diff --git a/libraries/logic/minecraft/forge/LegacyForge.h b/libraries/logic/minecraft/forge/LegacyForge.h
deleted file mode 100644
index f51d5e85..00000000
--- a/libraries/logic/minecraft/forge/LegacyForge.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "minecraft/Mod.h"
-
-class MinecraftForge : public Mod
-{
-public:
- MinecraftForge(const QString &file);
- bool FixVersionIfNeeded(QString newVersion);
-};
diff --git a/libraries/logic/minecraft/ftb/FTBPlugin.cpp b/libraries/logic/minecraft/ftb/FTBPlugin.cpp
deleted file mode 100644
index a142c106..00000000
--- a/libraries/logic/minecraft/ftb/FTBPlugin.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-#include "FTBPlugin.h"
-#include <Env.h>
-#include "FTBVersion.h"
-#include "LegacyFTBInstance.h"
-#include "OneSixFTBInstance.h"
-#include <BaseInstance.h>
-#include <InstanceList.h>
-#include <minecraft/MinecraftVersionList.h>
-#include <settings/INISettingsObject.h>
-#include <FileSystem.h>
-#include "QDebug"
-#include <QXmlStreamReader>
-#include <QRegularExpression>
-
-struct FTBRecord
-{
- QString dirName;
- QString name;
- QString logo;
- QString iconKey;
- QString mcVersion;
- QString description;
- QString instanceDir;
- QString templateDir;
- bool operator==(const FTBRecord other) const
- {
- return instanceDir == other.instanceDir;
- }
-};
-
-inline uint qHash(FTBRecord record)
-{
- return qHash(record.instanceDir);
-}
-
-QSet<FTBRecord> discoverFTBInstances(SettingsObjectPtr globalSettings)
-{
- QSet<FTBRecord> records;
- QDir dir = QDir(globalSettings->get("FTBLauncherLocal").toString());
- QDir dataDir = QDir(globalSettings->get("FTBRoot").toString());
- if (!dataDir.exists())
- {
- qDebug() << "The FTB directory specified does not exist. Please check your settings";
- return records;
- }
- else if (!dir.exists())
- {
- qDebug() << "The FTB launcher data directory specified does not exist. Please check "
- "your settings";
- return records;
- }
- dir.cd("ModPacks");
- auto allFiles = dir.entryList(QDir::Readable | QDir::Files, QDir::Name);
- for (auto filename : allFiles)
- {
- if (!filename.endsWith(".xml"))
- continue;
- auto fpath = dir.absoluteFilePath(filename);
- QFile f(fpath);
- qDebug() << "Discovering FTB instances -- " << fpath;
- if (!f.open(QFile::ReadOnly))
- continue;
-
- // read the FTB packs XML.
- QXmlStreamReader reader(&f);
- while (!reader.atEnd())
- {
- switch (reader.readNext())
- {
- case QXmlStreamReader::StartElement:
- {
- if (reader.name() == "modpack")
- {
- QXmlStreamAttributes attrs = reader.attributes();
- FTBRecord record;
- record.dirName = attrs.value("dir").toString();
- record.instanceDir = dataDir.absoluteFilePath(record.dirName);
- record.templateDir = dir.absoluteFilePath(record.dirName);
- QDir test(record.instanceDir);
- qDebug() << dataDir.absolutePath() << record.instanceDir << record.dirName;
- if (!test.exists())
- continue;
- record.name = attrs.value("name").toString();
- record.logo = attrs.value("logo").toString();
- QString logo = record.logo;
- record.iconKey = logo.remove(QRegularExpression("\\..*"));
- auto customVersions = attrs.value("customMCVersions");
- if (!customVersions.isNull())
- {
- QMap<QString, QString> versionMatcher;
- QString customVersionsStr = customVersions.toString();
- QStringList list = customVersionsStr.split(';');
- for (auto item : list)
- {
- auto segment = item.split('^');
- if (segment.size() != 2)
- {
- qCritical() << "FTB: Segment of size < 2 in "
- << customVersionsStr;
- continue;
- }
- versionMatcher[segment[0]] = segment[1];
- }
- auto actualVersion = attrs.value("version").toString();
- if (versionMatcher.contains(actualVersion))
- {
- record.mcVersion = versionMatcher[actualVersion];
- }
- else
- {
- record.mcVersion = attrs.value("mcVersion").toString();
- }
- }
- else
- {
- record.mcVersion = attrs.value("mcVersion").toString();
- }
- record.description = attrs.value("description").toString();
- records.insert(record);
- }
- break;
- }
- case QXmlStreamReader::EndElement:
- break;
- case QXmlStreamReader::Characters:
- break;
- default:
- break;
- }
- }
- f.close();
- }
- return records;
-}
-
-InstancePtr loadInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record)
-{
- InstancePtr inst;
-
- auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg"));
- m_settings->registerSetting("InstanceType", "Legacy");
-
- qDebug() << "Loading existing " << record.name;
-
- QString inst_type = m_settings->get("InstanceType").toString();
- if (inst_type == "LegacyFTB")
- {
- inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- else if (inst_type == "OneSixFTB")
- {
- inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- else
- {
- return nullptr;
- }
- qDebug() << "Construction " << record.instanceDir;
-
- SettingsObject::Lock lock(inst->settings());
- inst->init();
- qDebug() << "Init " << record.instanceDir;
- inst->setGroupInitial("FTB");
- /**
- * FIXME: this does not respect the user's preferences. BUT, it would work nicely with the planned pack support
- * -> instead of changing the user values, change pack values (defaults you can look at and revert to)
- */
- /*
- inst->setName(record.name);
- inst->setIconKey(record.iconKey);
- inst->setNotes(record.description);
- */
- if (inst->intendedVersionId() != record.mcVersion)
- {
- inst->setIntendedVersionId(record.mcVersion);
- }
- qDebug() << "Post-Process " << record.instanceDir;
- if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap))
- {
- return nullptr;
- }
- qDebug() << "Final " << record.instanceDir;
- return inst;
-}
-
-InstancePtr createInstance(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, const FTBRecord & record)
-{
- QDir rootDir(record.instanceDir);
-
- InstancePtr inst;
-
- qDebug() << "Converting " << record.name << " as new.";
-
- auto mcVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", record.mcVersion));
- if (!mcVersion)
- {
- qCritical() << "Can't load instance " << record.instanceDir
- << " because minecraft version " << record.mcVersion
- << " can't be resolved.";
- return nullptr;
- }
-
- if (!rootDir.exists() && !rootDir.mkpath("."))
- {
- qCritical() << "Can't create instance folder" << record.instanceDir;
- return nullptr;
- }
-
- auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg"));
- m_settings->registerSetting("InstanceType", "Legacy");
-
- if (mcVersion->usesLegacyLauncher())
- {
- m_settings->set("InstanceType", "LegacyFTB");
- inst.reset(new LegacyFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- else
- {
- m_settings->set("InstanceType", "OneSixFTB");
- inst.reset(new OneSixFTBInstance(globalSettings, m_settings, record.instanceDir));
- }
- // initialize
- {
- SettingsObject::Lock lock(inst->settings());
- inst->setIntendedVersionId(mcVersion->descriptor());
- inst->init();
- inst->setGroupInitial("FTB");
- inst->setName(record.name);
- inst->setIconKey(record.iconKey);
- inst->setNotes(record.description);
- qDebug() << "Post-Process " << record.instanceDir;
- if (!InstanceList::continueProcessInstance(inst, InstanceList::NoCreateError, record.instanceDir, groupMap))
- {
- return nullptr;
- }
- }
- return inst;
-}
-
-void FTBPlugin::loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList)
-{
- // nothing to load when we don't have
- if (globalSettings->get("TrackFTBInstances").toBool() != true)
- {
- return;
- }
-
- auto records = discoverFTBInstances(globalSettings);
- if (!records.size())
- {
- qDebug() << "No FTB instances to load.";
- return;
- }
- qDebug() << "Loading FTB instances! -- got " << records.size();
- // process the records we acquired.
- for (auto record : records)
- {
- qDebug() << "Loading FTB instance from " << record.instanceDir;
- QString iconKey = record.iconKey;
- // MMC->icons()->addIcon(iconKey, iconKey, FS::PathCombine(record.templateDir, record.logo), MMCIcon::Transient);
- auto settingsFilePath = FS::PathCombine(record.instanceDir, "instance.cfg");
- qDebug() << "ICON get!";
-
- if (QFileInfo(settingsFilePath).exists())
- {
- auto instPtr = loadInstance(globalSettings, groupMap, record);
- if (!instPtr)
- {
- qWarning() << "Couldn't load instance config:" << settingsFilePath;
- if(!QFile::remove(settingsFilePath))
- {
- qWarning() << "Couldn't remove broken instance config!";
- continue;
- }
- // failed to load, but removed the poisonous file
- }
- else
- {
- tempList.append(InstancePtr(instPtr));
- continue;
- }
- }
- auto instPtr = createInstance(globalSettings, groupMap, record);
- if (!instPtr)
- {
- qWarning() << "Couldn't create FTB instance!";
- continue;
- }
- tempList.append(InstancePtr(instPtr));
- }
-}
-
-#ifdef Q_OS_WIN32
-#include <windows.h>
-static const int APPDATA_BUFFER_SIZE = 1024;
-#endif
-
-static QString getLocalCacheStorageLocation()
-{
- QString ftbDefault;
-#ifdef Q_OS_WIN32
- wchar_t buf[APPDATA_BUFFER_SIZE];
- if (GetEnvironmentVariableW(L"LOCALAPPDATA", buf, APPDATA_BUFFER_SIZE)) // local
- {
- ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher");
- }
- else if (GetEnvironmentVariableW(L"APPDATA", buf, APPDATA_BUFFER_SIZE)) // roaming
- {
- ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher");
- }
- else
- {
- qCritical() << "Your LOCALAPPDATA and APPDATA folders are missing!"
- " If you are on windows, this means your system is broken.";
- }
-#elif defined(Q_OS_MAC)
- ftbDefault = FS::PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher");
-#else
- ftbDefault = QDir::home().absoluteFilePath(".ftblauncher");
-#endif
- return ftbDefault;
-}
-
-
-static QString getRoamingStorageLocation()
-{
- QString ftbDefault;
-#ifdef Q_OS_WIN32
- wchar_t buf[APPDATA_BUFFER_SIZE];
- QString cacheStorage;
- if (GetEnvironmentVariableW(L"APPDATA", buf, APPDATA_BUFFER_SIZE))
- {
- ftbDefault = QDir(QString::fromWCharArray(buf)).absoluteFilePath("ftblauncher");
- }
- else
- {
- qCritical() << "Your APPDATA folder is missing! If you are on windows, this means your system is broken.";
- }
-#elif defined(Q_OS_MAC)
- ftbDefault = FS::PathCombine(QDir::homePath(), "Library/Application Support/ftblauncher");
-#else
- ftbDefault = QDir::home().absoluteFilePath(".ftblauncher");
-#endif
- return ftbDefault;
-}
-
-void FTBPlugin::initialize(SettingsObjectPtr globalSettings)
-{
- // FTB
- globalSettings->registerSetting("TrackFTBInstances", false);
- QString ftbRoaming = getRoamingStorageLocation();
- QString ftbLocal = getLocalCacheStorageLocation();
-
- globalSettings->registerSetting("FTBLauncherRoaming", ftbRoaming);
- globalSettings->registerSetting("FTBLauncherLocal", ftbLocal);
- qDebug() << "FTB Launcher paths:" << globalSettings->get("FTBLauncherRoaming").toString()
- << "and" << globalSettings->get("FTBLauncherLocal").toString();
-
- globalSettings->registerSetting("FTBRoot");
- if (globalSettings->get("FTBRoot").isNull())
- {
- QString ftbRoot;
- QFile f(QDir(globalSettings->get("FTBLauncherRoaming").toString()).absoluteFilePath("ftblaunch.cfg"));
- qDebug() << "Attempting to read" << f.fileName();
- if (f.open(QFile::ReadOnly))
- {
- const QString data = QString::fromLatin1(f.readAll());
- QRegularExpression exp("installPath=(.*)");
- ftbRoot = QDir::cleanPath(exp.match(data).captured(1));
-#ifdef Q_OS_WIN32
- if (!ftbRoot.isEmpty())
- {
- if (ftbRoot.at(0).isLetter() && ftbRoot.size() > 1 && ftbRoot.at(1) == '/')
- {
- ftbRoot.remove(1, 1);
- }
- }
-#endif
- if (ftbRoot.isEmpty())
- {
- qDebug() << "Failed to get FTB root path";
- }
- else
- {
- qDebug() << "FTB is installed at" << ftbRoot;
- globalSettings->set("FTBRoot", ftbRoot);
- }
- }
- else
- {
- qWarning() << "Couldn't open" << f.fileName() << ":" << f.errorString();
- qWarning() << "This is perfectly normal if you don't have FTB installed";
- }
- }
-}
diff --git a/libraries/logic/minecraft/ftb/FTBPlugin.h b/libraries/logic/minecraft/ftb/FTBPlugin.h
deleted file mode 100644
index 6851d8a5..00000000
--- a/libraries/logic/minecraft/ftb/FTBPlugin.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <BaseInstance.h>
-
-#include "multimc_logic_export.h"
-
-// Pseudo-plugin for FTB related things. Super derpy!
-class MULTIMC_LOGIC_EXPORT FTBPlugin
-{
-public:
- static void initialize(SettingsObjectPtr globalSettings);
- static void loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QString> &groupMap, QList<InstancePtr> &tempList);
-};
diff --git a/libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp b/libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp
deleted file mode 100644
index f5faacae..00000000
--- a/libraries/logic/minecraft/ftb/FTBProfileStrategy.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "FTBProfileStrategy.h"
-#include "OneSixFTBInstance.h"
-
-#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
-#include <FileSystem.h>
-
-#include <QDir>
-#include <QUuid>
-#include <QJsonDocument>
-#include <QJsonArray>
-
-FTBProfileStrategy::FTBProfileStrategy(OneSixFTBInstance* instance) : OneSixProfileStrategy(instance)
-{
-}
-
-void FTBProfileStrategy::loadDefaultBuiltinPatches()
-{
- // FIXME: this should be here, but it needs us to be able to deal with multiple libraries paths
- // OneSixProfileStrategy::loadDefaultBuiltinPatches();
- auto mcVersion = m_instance->intendedVersionId();
- auto nativeInstance = dynamic_cast<OneSixFTBInstance *>(m_instance);
-
- ProfilePatchPtr minecraftPatch;
- {
- auto mcJson = m_instance->versionsPath().absoluteFilePath(mcVersion + "/" + mcVersion + ".json");
- // load up the base minecraft patch
- if(QFile::exists(mcJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
- file->fileId = "net.minecraft";
- file->name = QObject::tr("Minecraft (tracked)");
- file->setVanilla(true);
- if(file->version.isEmpty())
- {
- file->version = mcVersion;
- }
- for(auto addLib: file->libraries)
- {
- addLib->setHint("local");
- addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
- }
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- throw VersionIncomplete("net.minecraft");
- }
- minecraftPatch->setOrder(-2);
- }
- profile->appendPatch(minecraftPatch);
-
- ProfilePatchPtr packPatch;
- {
- auto mcJson = m_instance->minecraftRoot() + "/pack.json";
- // load up the base minecraft patch
- if(QFile::exists(mcJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
-
- // adapt the loaded file - the FTB patch file format is different than ours.
- file->minecraftVersion.clear();
- for(auto addLib: file->libraries)
- {
- addLib->setHint("local");
- addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath());
- }
- file->fileId = "org.multimc.ftb.pack";
- file->setVanilla(true);
- file->name = QObject::tr("%1 (FTB pack)").arg(m_instance->name());
- if(file->version.isEmpty())
- {
- file->version = QObject::tr("Unknown");
- QFile versionFile (FS::PathCombine(m_instance->instanceRoot(), "version"));
- if(versionFile.exists())
- {
- if(versionFile.open(QIODevice::ReadOnly))
- {
- // FIXME: just guessing the encoding/charset here.
- auto version = QString::fromUtf8(versionFile.readAll());
- file->version = version;
- }
- }
- }
- packPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- throw VersionIncomplete("org.multimc.ftb.pack");
- }
- packPatch->setOrder(1);
- }
- profile->appendPatch(packPatch);
-
-}
-
-void FTBProfileStrategy::load()
-{
- profile->clearPatches();
-
- loadDefaultBuiltinPatches();
- loadUserPatches();
-}
-
-bool FTBProfileStrategy::saveOrder(ProfileUtils::PatchOrder order)
-{
- return false;
-}
-
-bool FTBProfileStrategy::resetOrder()
-{
- return false;
-}
-
-bool FTBProfileStrategy::installJarMods(QStringList filepaths)
-{
- return false;
-}
-
-bool FTBProfileStrategy::customizePatch(ProfilePatchPtr patch)
-{
- return false;
-}
-
-bool FTBProfileStrategy::revertPatch(ProfilePatchPtr patch)
-{
- return false;
-}
diff --git a/libraries/logic/minecraft/ftb/FTBProfileStrategy.h b/libraries/logic/minecraft/ftb/FTBProfileStrategy.h
deleted file mode 100644
index 522af098..00000000
--- a/libraries/logic/minecraft/ftb/FTBProfileStrategy.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include "minecraft/ProfileStrategy.h"
-#include "minecraft/onesix/OneSixProfileStrategy.h"
-
-class OneSixFTBInstance;
-
-class FTBProfileStrategy : public OneSixProfileStrategy
-{
-public:
- FTBProfileStrategy(OneSixFTBInstance * instance);
- virtual ~FTBProfileStrategy() {};
- virtual void load() override;
- virtual bool resetOrder() override;
- virtual bool saveOrder(ProfileUtils::PatchOrder order) override;
- virtual bool installJarMods(QStringList filepaths) override;
- virtual bool customizePatch (ProfilePatchPtr patch) override;
- virtual bool revertPatch (ProfilePatchPtr patch) override;
-
-protected:
- virtual void loadDefaultBuiltinPatches() override;
-};
diff --git a/libraries/logic/minecraft/ftb/FTBVersion.h b/libraries/logic/minecraft/ftb/FTBVersion.h
deleted file mode 100644
index 805319b4..00000000
--- a/libraries/logic/minecraft/ftb/FTBVersion.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-#include <minecraft/MinecraftVersion.h>
-
-class FTBVersion : public BaseVersion
-{
-public:
- FTBVersion(MinecraftVersionPtr parent) : m_version(parent){};
-
-public:
- virtual QString descriptor() override
- {
- return m_version->descriptor();
- }
-
- virtual QString name() override
- {
- return m_version->name();
- }
-
- virtual QString typeString() const override
- {
- return m_version->typeString();
- }
-
- MinecraftVersionPtr getMinecraftVersion()
- {
- return m_version;
- }
-
-private:
- MinecraftVersionPtr m_version;
-};
diff --git a/libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp b/libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp
deleted file mode 100644
index a7091f1d..00000000
--- a/libraries/logic/minecraft/ftb/LegacyFTBInstance.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "LegacyFTBInstance.h"
-#include <settings/INISettingsObject.h>
-#include <QDir>
-
-LegacyFTBInstance::LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
- LegacyInstance(globalSettings, settings, rootDir)
-{
-}
-
-QString LegacyFTBInstance::id() const
-{
- return "FTB/" + BaseInstance::id();
-}
-
-void LegacyFTBInstance::copy(const QDir &newDir)
-{
- // set the target instance to be plain Legacy
- INISettingsObject settings_obj(newDir.absoluteFilePath("instance.cfg"));
- settings_obj.registerSetting("InstanceType", "Legacy");
- QString inst_type = settings_obj.get("InstanceType").toString();
- settings_obj.set("InstanceType", "Legacy");
-}
-
-QString LegacyFTBInstance::typeName() const
-{
- return tr("Legacy FTB");
-}
diff --git a/libraries/logic/minecraft/ftb/LegacyFTBInstance.h b/libraries/logic/minecraft/ftb/LegacyFTBInstance.h
deleted file mode 100644
index 7178bca4..00000000
--- a/libraries/logic/minecraft/ftb/LegacyFTBInstance.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "minecraft/legacy/LegacyInstance.h"
-
-class LegacyFTBInstance : public LegacyInstance
-{
- Q_OBJECT
-public:
- explicit LegacyFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual QString id() const;
- virtual void copy(const QDir &newDir);
- virtual QString typeName() const;
- bool canExport() const override
- {
- return false;
- }
-};
diff --git a/libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp b/libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp
deleted file mode 100644
index 81e939a1..00000000
--- a/libraries/logic/minecraft/ftb/OneSixFTBInstance.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "OneSixFTBInstance.h"
-#include "FTBProfileStrategy.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/GradleSpecifier.h"
-#include "tasks/SequentialTask.h"
-#include <settings/INISettingsObject.h>
-#include <FileSystem.h>
-
-#include <QJsonArray>
-
-OneSixFTBInstance::OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
- OneSixInstance(globalSettings, settings, rootDir)
-{
- m_globalSettings = globalSettings;
-}
-
-void OneSixFTBInstance::copy(const QDir &newDir)
-{
- QStringList libraryNames;
- // create patch file
- {
- qDebug()<< "Creating patch file for FTB instance...";
- QFile f(minecraftRoot() + "/pack.json");
- if (!f.open(QFile::ReadOnly))
- {
- qCritical() << "Couldn't open" << f.fileName() << ":" << f.errorString();
- return;
- }
- QJsonObject root = QJsonDocument::fromJson(f.readAll()).object();
- QJsonArray libs = root.value("libraries").toArray();
- QJsonArray outLibs;
- for (auto lib : libs)
- {
- QJsonObject libObj = lib.toObject();
- libObj.insert("MMC-hint", QString("local"));
- libObj.insert("insert", QString("prepend"));
- libraryNames.append(libObj.value("name").toString());
- outLibs.append(libObj);
- }
- root.remove("libraries");
- root.remove("id");
-
- // HACK HACK HACK HACK
- // A workaround for a problem in MultiMC, triggered by a historical problem in FTB,
- // triggered by Mojang getting their library versions wrong in 1.7.10
- if(intendedVersionId() == "1.7.10")
- {
- auto insert = [&outLibs, &libraryNames](QString name)
- {
- QJsonObject libObj;
- libObj.insert("insert", QString("replace"));
- libObj.insert("name", name);
- libraryNames.push_back(name);
- outLibs.prepend(libObj);
- };
- insert("com.google.guava:guava:16.0");
- insert("org.apache.commons:commons-lang3:3.2.1");
- }
- root.insert("+libraries", outLibs);
- root.insert("order", 1);
- root.insert("fileId", QString("org.multimc.ftb.pack.json"));
- root.insert("name", name());
- root.insert("mcVersion", intendedVersionId());
- root.insert("version", intendedVersionId());
- FS::ensureFilePathExists(newDir.absoluteFilePath("patches/ftb.json"));
- QFile out(newDir.absoluteFilePath("patches/ftb.json"));
- if (!out.open(QFile::WriteOnly | QFile::Truncate))
- {
- qCritical() << "Couldn't open" << out.fileName() << ":" << out.errorString();
- return;
- }
- out.write(QJsonDocument(root).toJson());
- }
- // copy libraries
- {
- qDebug() << "Copying FTB libraries";
- for (auto library : libraryNames)
- {
- GradleSpecifier lib(library);
- const QString out = QDir::current().absoluteFilePath("libraries/" + lib.toPath());
- if (QFile::exists(out))
- {
- continue;
- }
- if (!FS::ensureFilePathExists(out))
- {
- qCritical() << "Couldn't create folder structure for" << out;
- }
- if (!QFile::copy(librariesPath().absoluteFilePath(lib.toPath()), out))
- {
- qCritical() << "Couldn't copy" << QString(lib);
- }
- }
- }
- // now set the target instance to be plain OneSix
- INISettingsObject settings_obj(newDir.absoluteFilePath("instance.cfg"));
- settings_obj.registerSetting("InstanceType", "Legacy");
- QString inst_type = settings_obj.get("InstanceType").toString();
- settings_obj.set("InstanceType", "OneSix");
-}
-
-QString OneSixFTBInstance::id() const
-{
- return "FTB/" + BaseInstance::id();
-}
-
-QDir OneSixFTBInstance::librariesPath() const
-{
- return QDir(m_globalSettings->get("FTBRoot").toString() + "/libraries");
-}
-
-QDir OneSixFTBInstance::versionsPath() const
-{
- return QDir(m_globalSettings->get("FTBRoot").toString() + "/versions");
-}
-
-bool OneSixFTBInstance::providesVersionFile() const
-{
- return true;
-}
-
-void OneSixFTBInstance::createProfile()
-{
- m_profile.reset(new MinecraftProfile(new FTBProfileStrategy(this)));
-}
-
-std::shared_ptr<Task> OneSixFTBInstance::createUpdateTask()
-{
- return OneSixInstance::createUpdateTask();
-}
-
-QString OneSixFTBInstance::typeName() const
-{
- return tr("OneSix FTB");
-}
-
-#include "OneSixFTBInstance.moc"
diff --git a/libraries/logic/minecraft/ftb/OneSixFTBInstance.h b/libraries/logic/minecraft/ftb/OneSixFTBInstance.h
deleted file mode 100644
index e7f8f485..00000000
--- a/libraries/logic/minecraft/ftb/OneSixFTBInstance.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "minecraft/onesix/OneSixInstance.h"
-
-class OneSixFTBInstance : public OneSixInstance
-{
- Q_OBJECT
-public:
- explicit OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~OneSixFTBInstance(){};
-
- void copy(const QDir &newDir) override;
-
- virtual void createProfile() override;
-
- virtual std::shared_ptr<Task> createUpdateTask() override;
-
- virtual QString id() const override;
-
- QDir librariesPath() const override;
- QDir versionsPath() const override;
- bool providesVersionFile() const override;
- virtual QString typeName() const override;
- bool canExport() const override
- {
- return false;
- }
-private:
- SettingsObjectPtr m_globalSettings;
-};
diff --git a/libraries/logic/minecraft/legacy/LegacyInstance.cpp b/libraries/logic/minecraft/legacy/LegacyInstance.cpp
deleted file mode 100644
index f8264f20..00000000
--- a/libraries/logic/minecraft/legacy/LegacyInstance.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Copyright 2013-2015 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 <QFileInfo>
-#include <QDir>
-#include <settings/Setting.h>
-
-#include "LegacyInstance.h"
-
-#include "minecraft/legacy/LegacyUpdate.h"
-#include "launch/LaunchTask.h"
-#include <launch/steps/LaunchMinecraft.h>
-#include <launch/steps/PostLaunchCommand.h>
-#include <launch/steps/ModMinecraftJar.h>
-#include <launch/steps/Update.h>
-#include <launch/steps/PreLaunchCommand.h>
-#include <launch/steps/TextPrint.h>
-#include <launch/steps/CheckJava.h>
-#include "minecraft/ModList.h"
-#include "minecraft/WorldList.h"
-#include <MMCZip.h>
-#include <FileSystem.h>
-
-LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : MinecraftInstance(globalSettings, settings, rootDir)
-{
- m_lwjglFolderSetting = globalSettings->getSetting("LWJGLDir");
- settings->registerSetting("NeedsRebuild", true);
- settings->registerSetting("ShouldUpdate", false);
- settings->registerSetting("JarVersion", "Unknown");
- settings->registerSetting("LwjglVersion", "2.9.0");
- settings->registerSetting("IntendedJarVersion", "");
- /*
- * custom base jar has no default. it is determined in code... see the accessor methods for
- *it
- *
- * for instances that DO NOT have the CustomBaseJar setting (legacy instances),
- * [.]minecraft/bin/mcbackup.jar is the default base jar
- */
- settings->registerSetting("UseCustomBaseJar", true);
- settings->registerSetting("CustomBaseJar", "");
-}
-
-QString LegacyInstance::baseJar() const
-{
- bool customJar = m_settings->get("UseCustomBaseJar").toBool();
- if (customJar)
- {
- return customBaseJar();
- }
- else
- return defaultBaseJar();
-}
-
-QString LegacyInstance::customBaseJar() const
-{
- QString value = m_settings->get("CustomBaseJar").toString();
- if (value.isNull() || value.isEmpty())
- {
- return defaultCustomBaseJar();
- }
- return value;
-}
-
-void LegacyInstance::setCustomBaseJar(QString val)
-{
- if (val.isNull() || val.isEmpty() || val == defaultCustomBaseJar())
- m_settings->reset("CustomBaseJar");
- else
- m_settings->set("CustomBaseJar", val);
-}
-
-void LegacyInstance::setShouldUseCustomBaseJar(bool val)
-{
- m_settings->set("UseCustomBaseJar", val);
-}
-
-bool LegacyInstance::shouldUseCustomBaseJar() const
-{
- return m_settings->get("UseCustomBaseJar").toBool();
-}
-
-
-std::shared_ptr<Task> LegacyInstance::createUpdateTask()
-{
- // make sure the jar mods list is initialized by asking for it.
- auto list = jarModList();
- // create an update task
- return std::shared_ptr<Task>(new LegacyUpdate(this, this));
-}
-
-std::shared_ptr<LaunchTask> LegacyInstance::createLaunchTask(AuthSessionPtr session)
-{
- auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
- auto pptr = process.get();
-
- // print a header
- {
- process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
- }
- {
- auto step = std::make_shared<CheckJava>(pptr);
- process->appendStep(step);
- }
- // run pre-launch command if that's needed
- if(getPreLaunchCommand().size())
- {
- auto step = std::make_shared<PreLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- // if we aren't in offline mode,.
- if(session->status != AuthSession::PlayableOffline)
- {
- process->appendStep(std::make_shared<Update>(pptr));
- }
- // if there are any jar mods
- if(getJarMods().size())
- {
- auto step = std::make_shared<ModMinecraftJar>(pptr);
- process->appendStep(step);
- }
- // actually launch the game
- {
- auto step = std::make_shared<LaunchMinecraft>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- step->setAuthSession(session);
- process->appendStep(step);
- }
- // run post-exit command if that's needed
- if(getPostExitCommand().size())
- {
- auto step = std::make_shared<PostLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- if (session)
- {
- process->setCensorFilter(createCensorFilterFromSession(session));
- }
- return process;
-}
-
-std::shared_ptr<Task> LegacyInstance::createJarModdingTask()
-{
- class JarModTask : public Task
- {
- public:
- explicit JarModTask(std::shared_ptr<LegacyInstance> inst) : Task(nullptr), m_inst(inst)
- {
- }
- virtual void executeTask()
- {
- if (!m_inst->shouldRebuild())
- {
- emitSucceeded();
- return;
- }
-
- // Get the mod list
- auto modList = m_inst->getJarMods();
-
- QFileInfo runnableJar(m_inst->runnableJar());
- QFileInfo baseJar(m_inst->baseJar());
- bool base_is_custom = m_inst->shouldUseCustomBaseJar();
-
- // Nothing to do if there are no jar mods to install, no backup and just the mc jar
- if (base_is_custom)
- {
- // yes, this can happen if the instance only has the runnable jar and not the base jar
- // it *could* be assumed that such an instance is vanilla, but that wouldn't be safe
- // because that's not something mmc4 guarantees
- if (runnableJar.isFile() && !baseJar.exists() && modList.empty())
- {
- m_inst->setShouldRebuild(false);
- emitSucceeded();
- return;
- }
-
- setStatus(tr("Installing mods: Backing up minecraft.jar ..."));
- if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
- {
- emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
- "be used on next run.");
- m_inst->setShouldRebuild(true);
- m_inst->setShouldUpdate(true);
- m_inst->setShouldUseCustomBaseJar(false);
- return;
- }
- }
-
- if (!baseJar.exists())
- {
- emitFailed("The base jar " + baseJar.filePath() + " does not exist");
- return;
- }
-
- if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
- {
- emitFailed("Failed to delete old minecraft.jar");
- return;
- }
-
- setStatus(tr("Installing mods: Opening minecraft.jar ..."));
-
- QString outputJarPath = runnableJar.filePath();
- QString inputJarPath = baseJar.filePath();
-
- if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
- {
- emitFailed(tr("Failed to create the custom Minecraft jar file."));
- return;
- }
- m_inst->setShouldRebuild(false);
- // inst->UpdateVersion(true);
- emitSucceeded();
- return;
-
- }
- std::shared_ptr<LegacyInstance> m_inst;
- };
- return std::make_shared<JarModTask>(std::dynamic_pointer_cast<LegacyInstance>(shared_from_this()));
-}
-
-QString LegacyInstance::createLaunchScript(AuthSessionPtr session)
-{
- QString launchScript;
-
- // window size
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- {
- windowParams = "max";
- }
- else
- {
- windowParams = QString("%1x%2").arg(settings()->get("MinecraftWinWidth").toInt()).arg(settings()->get("MinecraftWinHeight").toInt());
- }
-
- QString lwjgl = QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath();
- launchScript += "userName " + session->player_name + "\n";
- launchScript += "sessionId " + session->session + "\n";
- launchScript += "windowTitle " + windowTitle() + "\n";
- launchScript += "windowParams " + windowParams + "\n";
- launchScript += "lwjgl " + lwjgl + "\n";
- launchScript += "launcher legacy\n";
- return launchScript;
-}
-
-void LegacyInstance::cleanupAfterRun()
-{
- // FIXME: delete the launcher and icons and whatnot.
-}
-
-std::shared_ptr<ModList> LegacyInstance::coreModList() const
-{
- if (!core_mod_list)
- {
- core_mod_list.reset(new ModList(coreModsDir()));
- }
- core_mod_list->update();
- return core_mod_list;
-}
-
-std::shared_ptr<ModList> LegacyInstance::jarModList() const
-{
- if (!jar_mod_list)
- {
- auto list = new ModList(jarModsDir(), modListFile());
- connect(list, SIGNAL(changed()), SLOT(jarModsChanged()));
- jar_mod_list.reset(list);
- }
- jar_mod_list->update();
- return jar_mod_list;
-}
-
-QList<Mod> LegacyInstance::getJarMods() const
-{
- return jarModList()->allMods();
-}
-
-void LegacyInstance::jarModsChanged()
-{
- qDebug() << "Jar mods of instance " << name() << " have changed. Jar will be rebuilt.";
- setShouldRebuild(true);
-}
-
-std::shared_ptr<ModList> LegacyInstance::loaderModList() const
-{
- if (!loader_mod_list)
- {
- loader_mod_list.reset(new ModList(loaderModsDir()));
- }
- loader_mod_list->update();
- return loader_mod_list;
-}
-
-std::shared_ptr<ModList> LegacyInstance::texturePackList() const
-{
- if (!texture_pack_list)
- {
- texture_pack_list.reset(new ModList(texturePacksDir()));
- }
- texture_pack_list->update();
- return texture_pack_list;
-}
-
-std::shared_ptr<WorldList> LegacyInstance::worldList() const
-{
- if (!m_world_list)
- {
- m_world_list.reset(new WorldList(savesDir()));
- }
- return m_world_list;
-}
-
-QString LegacyInstance::jarModsDir() const
-{
- return FS::PathCombine(instanceRoot(), "instMods");
-}
-
-QString LegacyInstance::binDir() const
-{
- return FS::PathCombine(minecraftRoot(), "bin");
-}
-
-QString LegacyInstance::libDir() const
-{
- return FS::PathCombine(minecraftRoot(), "lib");
-}
-
-QString LegacyInstance::savesDir() const
-{
- return FS::PathCombine(minecraftRoot(), "saves");
-}
-
-QString LegacyInstance::loaderModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "mods");
-}
-
-QString LegacyInstance::coreModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "coremods");
-}
-
-QString LegacyInstance::resourceDir() const
-{
- return FS::PathCombine(minecraftRoot(), "resources");
-}
-QString LegacyInstance::texturePacksDir() const
-{
- return FS::PathCombine(minecraftRoot(), "texturepacks");
-}
-
-QString LegacyInstance::runnableJar() const
-{
- return FS::PathCombine(binDir(), "minecraft.jar");
-}
-
-QString LegacyInstance::modListFile() const
-{
- return FS::PathCombine(instanceRoot(), "modlist");
-}
-
-QString LegacyInstance::instanceConfigFolder() const
-{
- return FS::PathCombine(minecraftRoot(), "config");
-}
-
-bool LegacyInstance::shouldRebuild() const
-{
- return m_settings->get("NeedsRebuild").toBool();
-}
-
-void LegacyInstance::setShouldRebuild(bool val)
-{
- m_settings->set("NeedsRebuild", val);
-}
-
-QString LegacyInstance::currentVersionId() const
-{
- return m_settings->get("JarVersion").toString();
-}
-
-QString LegacyInstance::lwjglVersion() const
-{
- return m_settings->get("LwjglVersion").toString();
-}
-
-void LegacyInstance::setLWJGLVersion(QString val)
-{
- m_settings->set("LwjglVersion", val);
-}
-
-QString LegacyInstance::intendedVersionId() const
-{
- return m_settings->get("IntendedJarVersion").toString();
-}
-
-bool LegacyInstance::setIntendedVersionId(QString version)
-{
- settings()->set("IntendedJarVersion", version);
- setShouldUpdate(true);
- return true;
-}
-
-bool LegacyInstance::shouldUpdate() const
-{
- QVariant var = settings()->get("ShouldUpdate");
- if (!var.isValid() || var.toBool() == false)
- {
- return intendedVersionId() != currentVersionId();
- }
- return true;
-}
-
-void LegacyInstance::setShouldUpdate(bool val)
-{
- settings()->set("ShouldUpdate", val);
-}
-
-QString LegacyInstance::defaultBaseJar() const
-{
- return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
-}
-
-QString LegacyInstance::defaultCustomBaseJar() const
-{
- return FS::PathCombine(binDir(), "mcbackup.jar");
-}
-
-QString LegacyInstance::lwjglFolder() const
-{
- return m_lwjglFolderSetting->get().toString();
-}
-
-QString LegacyInstance::typeName() const
-{
- return tr("Legacy");
-}
diff --git a/libraries/logic/minecraft/legacy/LegacyInstance.h b/libraries/logic/minecraft/legacy/LegacyInstance.h
deleted file mode 100644
index 3bef240d..00000000
--- a/libraries/logic/minecraft/legacy/LegacyInstance.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "minecraft/MinecraftInstance.h"
-
-#include "multimc_logic_export.h"
-
-class ModList;
-class Task;
-
-class MULTIMC_LOGIC_EXPORT LegacyInstance : public MinecraftInstance
-{
- Q_OBJECT
-public:
-
- explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
-
- virtual void init() override {};
-
- /// Path to the instance's minecraft.jar
- QString runnableJar() const;
-
- //! Path to the instance's modlist file.
- QString modListFile() const;
-
- /*
- ////// Edit Instance Dialog stuff //////
- virtual QList<BasePage *> getPages();
- virtual QString dialogTitle();
- */
-
- ////// Mod Lists //////
- std::shared_ptr<ModList> jarModList() const ;
- virtual QList< Mod > getJarMods() const override;
- std::shared_ptr<ModList> coreModList() const;
- std::shared_ptr<ModList> loaderModList() const;
- std::shared_ptr<ModList> texturePackList() const override;
- std::shared_ptr<WorldList> worldList() const override;
-
- ////// Directories //////
- QString libDir() const;
- QString savesDir() const;
- QString texturePacksDir() const;
- QString jarModsDir() const;
- QString binDir() const;
- QString loaderModsDir() const;
- QString coreModsDir() const;
- QString resourceDir() const;
- virtual QString instanceConfigFolder() const override;
-
- /// Get the curent base jar of this instance. By default, it's the
- /// versions/$version/$version.jar
- QString baseJar() const;
-
- /// the default base jar of this instance
- QString defaultBaseJar() const;
- /// the default custom base jar of this instance
- QString defaultCustomBaseJar() const;
-
- /*!
- * Whether or not custom base jar is used
- */
- bool shouldUseCustomBaseJar() const;
- void setShouldUseCustomBaseJar(bool val);
-
- /*!
- * The value of the custom base jar
- */
- QString customBaseJar() const;
- void setCustomBaseJar(QString val);
-
- /*!
- * Whether or not the instance's minecraft.jar needs to be rebuilt.
- * If this is true, when the instance launches, its jar mods will be
- * re-added to a fresh minecraft.jar file.
- */
- bool shouldRebuild() const;
- void setShouldRebuild(bool val);
-
- virtual QString currentVersionId() const override;
-
- //! The version of LWJGL that this instance uses.
- QString lwjglVersion() const;
-
- //! Where the lwjgl versions foor this instance can be found... HACK HACK HACK
- QString lwjglFolder() const;
-
- /// st the version of LWJGL libs this instance will use
- void setLWJGLVersion(QString val);
-
- virtual QString intendedVersionId() const override;
- virtual bool setIntendedVersionId(QString version) override;
-
- virtual QSet<QString> traits() override
- {
- return {"legacy-instance", "texturepacks"};
- };
-
- virtual bool shouldUpdate() const override;
- virtual void setShouldUpdate(bool val) override;
- virtual std::shared_ptr<Task> createUpdateTask() override;
-
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
-
- virtual std::shared_ptr<Task> createJarModdingTask() override;
-
- virtual QString createLaunchScript(AuthSessionPtr session) override;
-
- virtual void cleanupAfterRun() override;
-
- virtual QString typeName() const override;
-
- bool canExport() const override
- {
- return true;
- }
-
-protected:
- mutable std::shared_ptr<ModList> jar_mod_list;
- mutable std::shared_ptr<ModList> core_mod_list;
- mutable std::shared_ptr<ModList> loader_mod_list;
- mutable std::shared_ptr<ModList> texture_pack_list;
- mutable std::shared_ptr<WorldList> m_world_list;
- std::shared_ptr<Setting> m_lwjglFolderSetting;
-protected
-slots:
- virtual void jarModsChanged();
-};
diff --git a/libraries/logic/minecraft/legacy/LegacyUpdate.cpp b/libraries/logic/minecraft/legacy/LegacyUpdate.cpp
deleted file mode 100644
index 2d7e8dd2..00000000
--- a/libraries/logic/minecraft/legacy/LegacyUpdate.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/* Copyright 2013-2015 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 <QStringList>
-#include <quazip.h>
-#include <quazipfile.h>
-#include <QDebug>
-
-#include "Env.h"
-#include "BaseInstance.h"
-#include "net/URLConstants.h"
-#include "MMCZip.h"
-
-#include "LegacyUpdate.h"
-
-#include "LwjglVersionList.h"
-#include "minecraft/MinecraftVersionList.h"
-#include "minecraft/ModList.h"
-#include "LegacyInstance.h"
-#include <FileSystem.h>
-
-LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
-{
-}
-
-void LegacyUpdate::executeTask()
-{
- fmllibsStart();
-}
-
-void LegacyUpdate::fmllibsStart()
-{
- // Get the mod list
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- auto modList = inst->jarModList();
-
- bool forge_present = false;
-
- QString version = inst->intendedVersionId();
- auto & fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
- if (!fmlLibsMapping.contains(version))
- {
- lwjglStart();
- return;
- }
-
- auto &libList = fmlLibsMapping[version];
-
- // determine if we need some libs for FML or forge
- setStatus(tr("Checking for FML libraries..."));
- for (unsigned i = 0; i < modList->size(); i++)
- {
- auto &mod = modList->operator[](i);
-
- // do not use disabled mods.
- if (!mod.enabled())
- continue;
-
- if (mod.type() != Mod::MOD_ZIPFILE)
- continue;
-
- if (mod.mmc_id().contains("forge", Qt::CaseInsensitive))
- {
- forge_present = true;
- break;
- }
- if (mod.mmc_id().contains("fml", Qt::CaseInsensitive))
- {
- forge_present = true;
- break;
- }
- }
- // we don't...
- if (!forge_present)
- {
- lwjglStart();
- return;
- }
-
- // now check the lib folder inside the instance for files.
- for (auto &lib : libList)
- {
- QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
- if (libInfo.exists())
- continue;
- fmlLibsToProcess.append(lib);
- }
-
- // if everything is in place, there's nothing to do here...
- if (fmlLibsToProcess.isEmpty())
- {
- lwjglStart();
- return;
- }
-
- // download missing libs to our place
- setStatus(tr("Dowloading FML libraries..."));
- auto dljob = new NetJob("FML libraries");
- auto metacache = ENV.metacache();
- for (auto &lib : fmlLibsToProcess)
- {
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
- : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
- dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
- }
-
- connect(dljob, &NetJob::succeeded, this, &LegacyUpdate::fmllibsFinished);
- connect(dljob, &NetJob::failed, this, &LegacyUpdate::fmllibsFailed);
- connect(dljob, &NetJob::progress, this, &LegacyUpdate::progress);
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void LegacyUpdate::fmllibsFinished()
-{
- legacyDownloadJob.reset();
- if(!fmlLibsToProcess.isEmpty())
- {
- setStatus(tr("Copying FML libraries into the instance..."));
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- auto metacache = ENV.metacache();
- int index = 0;
- for (auto &lib : fmlLibsToProcess)
- {
- progress(index, fmlLibsToProcess.size());
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = FS::PathCombine(inst->libDir(), lib.filename);
- if(!FS::ensureFilePathExists(path))
- {
- emitFailed(tr("Failed creating FML library folder inside the instance."));
- return;
- }
- if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
- {
- emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
- return;
- }
- index++;
- }
- progress(index, fmlLibsToProcess.size());
- }
- lwjglStart();
-}
-
-void LegacyUpdate::fmllibsFailed(QString reason)
-{
- emitFailed(tr("Game update failed: it was impossible to fetch the required FML libraries. Reason: %1").arg(reason));
- return;
-}
-
-void LegacyUpdate::lwjglStart()
-{
- LegacyInstance *inst = (LegacyInstance *)m_inst;
-
- lwjglVersion = inst->lwjglVersion();
- lwjglTargetPath = FS::PathCombine(inst->lwjglFolder(), lwjglVersion);
- lwjglNativesPath = FS::PathCombine(lwjglTargetPath, "natives");
-
- // if the 'done' file exists, we don't have to download this again
- QFileInfo doneFile(FS::PathCombine(lwjglTargetPath, "done"));
- if (doneFile.exists())
- {
- jarStart();
- return;
- }
-
- auto list = std::dynamic_pointer_cast<LWJGLVersionList>(ENV.getVersionList("org.lwjgl.legacy"));
- if (!list->isLoaded())
- {
- emitFailed("Too soon! Let the LWJGL list load :)");
- return;
- }
-
- setStatus(tr("Downloading new LWJGL..."));
- auto version = std::dynamic_pointer_cast<LWJGLVersion>(list->findVersion(lwjglVersion));
- if (!version)
- {
- emitFailed("Game update failed: the selected LWJGL version is invalid.");
- return;
- }
-
- QString url = version->url();
- QUrl realUrl(url);
- QString hostname = realUrl.host();
- auto worker = ENV.qnam();
- QNetworkRequest req(realUrl);
- req.setRawHeader("Host", hostname.toLatin1());
- req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
- QNetworkReply *rep = worker->get(req);
-
- m_reply = std::shared_ptr<QNetworkReply>(rep);
- connect(rep, &QNetworkReply::downloadProgress, this, &LegacyUpdate::progress);
- connect(worker.get(), &QNetworkAccessManager::finished, this, &LegacyUpdate::lwjglFinished);
-}
-
-void LegacyUpdate::lwjglFinished(QNetworkReply *reply)
-{
- if (m_reply.get() != reply)
- {
- return;
- }
- if (reply->error() != QNetworkReply::NoError)
- {
- emitFailed("Failed to download: " + reply->errorString() +
- "\nSometimes you have to wait a bit if you download many LWJGL versions in "
- "a row. YMMV");
- return;
- }
- auto worker = ENV.qnam();
- // Here i check if there is a cookie for me in the reply and extract it
- QList<QNetworkCookie> cookies =
- qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader));
- if (cookies.count() != 0)
- {
- // you must tell which cookie goes with which url
- worker->cookieJar()->setCookiesFromUrl(cookies, QUrl("sourceforge.net"));
- }
-
- // here you can check for the 302 or whatever other header i need
- QVariant newLoc = reply->header(QNetworkRequest::LocationHeader);
- if (newLoc.isValid())
- {
- QString redirectedTo = reply->header(QNetworkRequest::LocationHeader).toString();
- QUrl realUrl(redirectedTo);
- QString hostname = realUrl.host();
- QNetworkRequest req(redirectedTo);
- req.setRawHeader("Host", hostname.toLatin1());
- req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
- QNetworkReply *rep = worker->get(req);
- connect(rep, &QNetworkReply::downloadProgress, this, &LegacyUpdate::progress);
- m_reply = std::shared_ptr<QNetworkReply>(rep);
- return;
- }
- QFile saveMe("lwjgl.zip");
- saveMe.open(QIODevice::WriteOnly);
- saveMe.write(m_reply->readAll());
- saveMe.close();
- setStatus(tr("Installing new LWJGL..."));
- extractLwjgl();
- jarStart();
-}
-void LegacyUpdate::extractLwjgl()
-{
- // make sure the directories are there
-
- bool success = FS::ensureFolderPathExists(lwjglNativesPath);
-
- if (!success)
- {
- emitFailed("Failed to extract the lwjgl libs - error when creating required folders.");
- return;
- }
-
- QuaZip zip("lwjgl.zip");
- if (!zip.open(QuaZip::mdUnzip))
- {
- emitFailed("Failed to extract the lwjgl libs - not a valid archive.");
- return;
- }
-
- // and now we are going to access files inside it
- QuaZipFile file(&zip);
- const QString jarNames[] = {"jinput.jar", "lwjgl_util.jar", "lwjgl.jar"};
- for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- emitFailed("Failed to extract the lwjgl libs - error while reading archive.");
- return;
- }
- QuaZipFileInfo info;
- QString name = file.getActualFileName();
- if (name.endsWith('/'))
- {
- file.close();
- continue;
- }
- QString destFileName;
- // Look for the jars
- for (int i = 0; i < 3; i++)
- {
- if (name.endsWith(jarNames[i]))
- {
- destFileName = FS::PathCombine(lwjglTargetPath, jarNames[i]);
- }
- }
- // Not found? look for the natives
- if (destFileName.isEmpty())
- {
-#ifdef Q_OS_WIN32
- QString nativesDir = "windows";
-#else
-#ifdef Q_OS_MAC
- QString nativesDir = "macosx";
-#else
- QString nativesDir = "linux";
-#endif
-#endif
- if (name.contains(nativesDir))
- {
- int lastSlash = name.lastIndexOf('/');
- int lastBackSlash = name.lastIndexOf('\\');
- if (lastSlash != -1)
- name = name.mid(lastSlash + 1);
- else if (lastBackSlash != -1)
- name = name.mid(lastBackSlash + 1);
- destFileName = FS::PathCombine(lwjglNativesPath, name);
- }
- }
- // Now if destFileName is still empty, go to the next file.
- if (!destFileName.isEmpty())
- {
- setStatus(tr("Installing new LWJGL - extracting ") + name + "...");
- QFile output(destFileName);
- output.open(QIODevice::WriteOnly);
- output.write(file.readAll());
- output.close();
- }
- file.close(); // do not forget to close!
- }
- zip.close();
- m_reply.reset();
- QFile doneFile(FS::PathCombine(lwjglTargetPath, "done"));
- doneFile.open(QIODevice::WriteOnly);
- doneFile.write("done.");
- doneFile.close();
-}
-
-void LegacyUpdate::lwjglFailed(QString reason)
-{
- emitFailed(tr("Bad stuff happened while trying to get the lwjgl libs: %1").arg(reason));
-}
-
-void LegacyUpdate::jarStart()
-{
- LegacyInstance *inst = (LegacyInstance *)m_inst;
- if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
- {
- emitSucceeded();
- return;
- }
-
- setStatus(tr("Checking for jar updates..."));
- // Make directories
- QDir binDir(inst->binDir());
- if (!binDir.exists() && !binDir.mkpath("."))
- {
- emitFailed("Failed to create bin folder.");
- return;
- }
-
- // Build a list of URLs that will need to be downloaded.
- setStatus(tr("Downloading new minecraft.jar ..."));
-
- QString version_id = inst->intendedVersionId();
-
- auto dljob = new NetJob("Minecraft.jar for version " + version_id);
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", URLConstants::getJarPath(version_id));
- dljob->addNetAction(CacheDownload::make(QUrl(URLConstants::getLegacyJarUrl(version_id)), entry));
- connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
- connect(dljob, SIGNAL(failed(QString)), SLOT(jarFailed(QString)));
- connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void LegacyUpdate::jarFinished()
-{
- // process the jar
- emitSucceeded();
-}
-
-void LegacyUpdate::jarFailed(QString reason)
-{
- // bad, bad
- emitFailed(tr("Failed to download the minecraft jar: %1.").arg(reason));
-}
diff --git a/libraries/logic/minecraft/legacy/LegacyUpdate.h b/libraries/logic/minecraft/legacy/LegacyUpdate.h
deleted file mode 100644
index c52bf934..00000000
--- a/libraries/logic/minecraft/legacy/LegacyUpdate.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QList>
-#include <QUrl>
-
-#include "net/NetJob.h"
-#include "tasks/Task.h"
-#include "minecraft/VersionFilterData.h"
-
-class MinecraftVersion;
-class BaseInstance;
-class QuaZip;
-class Mod;
-
-class LegacyUpdate : public Task
-{
- Q_OBJECT
-public:
- explicit LegacyUpdate(BaseInstance *inst, QObject *parent = 0);
- virtual void executeTask();
-
-private
-slots:
- void lwjglStart();
- void lwjglFinished(QNetworkReply *);
- void lwjglFailed(QString reason);
-
- void jarStart();
- void jarFinished();
- void jarFailed(QString reason);
-
- void fmllibsStart();
- void fmllibsFinished();
- void fmllibsFailed(QString reason);
-
- void extractLwjgl();
-
-private:
-
- std::shared_ptr<QNetworkReply> m_reply;
-
- // target version, determined during this task
- // MinecraftVersion *targetVersion;
- QString lwjglURL;
- QString lwjglVersion;
-
- QString lwjglTargetPath;
- QString lwjglNativesPath;
-
-private:
- NetJobPtr legacyDownloadJob;
- BaseInstance *m_inst = nullptr;
- QList<FMLlib> fmlLibsToProcess;
-};
diff --git a/libraries/logic/minecraft/legacy/LwjglVersionList.cpp b/libraries/logic/minecraft/legacy/LwjglVersionList.cpp
deleted file mode 100644
index bb017368..00000000
--- a/libraries/logic/minecraft/legacy/LwjglVersionList.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright 2013-2015 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 "LwjglVersionList.h"
-#include "Env.h"
-
-#include <QtNetwork>
-#include <QtXml>
-#include <QRegExp>
-
-#include <QDebug>
-
-#define RSS_URL "http://sourceforge.net/projects/java-game-lib/rss"
-
-LWJGLVersionList::LWJGLVersionList(QObject *parent) : BaseVersionList(parent)
-{
- setLoading(false);
-}
-
-QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- const PtrLWJGLVersion version = m_vlist.at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- return version->name();
-
- case Qt::ToolTipRole:
- return version->url();
-
- default:
- return QVariant();
- }
-}
-
-QVariant LWJGLVersionList::headerData(int section, Qt::Orientation orientation, int role) const
-{
- switch (role)
- {
- case Qt::DisplayRole:
- return tr("Version");
-
- case Qt::ToolTipRole:
- return tr("LWJGL version name.");
-
- default:
- return QVariant();
- }
-}
-
-int LWJGLVersionList::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-bool LWJGLVersionList::isLoading() const
-{
- return m_loading;
-}
-
-void LWJGLVersionList::loadList()
-{
- Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)");
-
- setLoading(true);
- auto worker = ENV.qnam();
- QNetworkRequest req(QUrl(RSS_URL));
- req.setRawHeader("Accept", "application/rss+xml, text/xml, */*");
- req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)");
- reply = worker->get(req);
- connect(reply, SIGNAL(finished()), SLOT(netRequestComplete()));
-}
-
-inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
-{
- QDomNodeList elementList = parent.elementsByTagName(tagname);
- if (elementList.count())
- return elementList.at(0).toElement();
- else
- return QDomElement();
-}
-
-void LWJGLVersionList::netRequestComplete()
-{
- if (reply->error() == QNetworkReply::NoError)
- {
- QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip");
- Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list", "LWJGL regex is invalid");
-
- QDomDocument doc;
-
- QString xmlErrorMsg;
- int errorLine;
- auto rawData = reply->readAll();
- if (!doc.setContent(rawData, false, &xmlErrorMsg, &errorLine))
- {
- failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " +
- QString::number(errorLine));
- setLoading(false);
- return;
- }
-
- QDomNodeList items = doc.elementsByTagName("item");
-
- QList<PtrLWJGLVersion> tempList;
-
- for (int i = 0; i < items.length(); i++)
- {
- Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list",
- "XML element isn't an element... wat?");
-
- QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link");
- if (linkElement.isNull())
- {
- qDebug() << "Link element" << i << "in RSS feed doesn't exist! Skipping.";
- continue;
- }
-
- QString link = linkElement.text();
-
- // Make sure it's a download link.
- if (link.endsWith("/download") && link.contains(lwjglRegex))
- {
- QString name = link.mid(lwjglRegex.indexIn(link) + 6);
- // Subtract 4 here to remove the .zip file extension.
- name = name.left(lwjglRegex.matchedLength() - 10);
-
- QUrl url(link);
- if (!url.isValid())
- {
- qWarning() << "LWJGL version URL isn't valid:" << link << "Skipping.";
- continue;
- }
- qDebug() << "Discovered LWGL version" << name << "at" << link;
- tempList.append(std::make_shared<LWJGLVersion>(name, link));
- }
- }
-
- beginResetModel();
- m_vlist.swap(tempList);
- endResetModel();
-
- qDebug() << "Loaded LWJGL list.";
- finished();
- }
- else
- {
- failed("Failed to load LWJGL list. Network error: " + reply->errorString());
- }
-
- setLoading(false);
- reply->deleteLater();
-}
-
-void LWJGLVersionList::failed(QString msg)
-{
- qCritical() << msg;
- emit loadListFailed(msg);
-}
-
-void LWJGLVersionList::finished()
-{
- emit loadListFinished();
-}
-
-void LWJGLVersionList::setLoading(bool loading)
-{
- m_loading = loading;
- emit loadingStateUpdated(m_loading);
-}
diff --git a/libraries/logic/minecraft/legacy/LwjglVersionList.h b/libraries/logic/minecraft/legacy/LwjglVersionList.h
deleted file mode 100644
index f043f6e2..00000000
--- a/libraries/logic/minecraft/legacy/LwjglVersionList.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QAbstractListModel>
-#include <QUrl>
-#include <QNetworkReply>
-#include <memory>
-
-#include "BaseVersion.h"
-#include "BaseVersionList.h"
-
-#include "multimc_logic_export.h"
-
-class LWJGLVersion;
-typedef std::shared_ptr<LWJGLVersion> PtrLWJGLVersion;
-
-class MULTIMC_LOGIC_EXPORT LWJGLVersion : public BaseVersion
-{
-public:
- LWJGLVersion(const QString &name, const QString &url)
- : m_name(name), m_url(url)
- {
- }
-
- virtual QString descriptor()
- {
- return m_name;
- }
-
- virtual QString name()
- {
- return m_name;
- }
-
- virtual QString typeString() const
- {
- return QObject::tr("Upstream");
- }
-
- QString url() const
- {
- return m_url;
- }
-
-protected:
- QString m_name;
- QString m_url;
-};
-
-class MULTIMC_LOGIC_EXPORT LWJGLVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- explicit LWJGLVersionList(QObject *parent = 0);
-
- bool isLoaded() override
- {
- return m_vlist.length() > 0;
- }
- virtual const BaseVersionPtr at(int i) const override
- {
- return m_vlist[i];
- }
-
- virtual Task* getLoadTask() override
- {
- return nullptr;
- }
-
- virtual void sortVersions() override {};
-
- virtual void updateListData(QList< BaseVersionPtr > versions) override {};
-
- int count() const override
- {
- return m_vlist.length();
- }
-
- virtual QVariant data(const QModelIndex &index, int role) const override;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- virtual int rowCount(const QModelIndex &parent) const override
- {
- return count();
- }
- virtual int columnCount(const QModelIndex &parent) const override;
-
- virtual bool isLoading() const;
- virtual bool errored() const
- {
- return m_errored;
- }
-
- virtual QString lastErrorMsg() const
- {
- return m_lastErrorMsg;
- }
-
-public
-slots:
- /*!
- * Loads the version list.
- * This is done asynchronously. On success, the loadListFinished() signal will
- * be emitted. The list model will be reset as well, resulting in the modelReset()
- * signal being emitted. Note that the model will be reset before loadListFinished() is
- * emitted.
- * If loading the list failed, the loadListFailed(QString msg),
- * signal will be emitted.
- */
- virtual void loadList();
-
-signals:
- /*!
- * Emitted when the list either starts or finishes loading.
- * \param loading Whether or not the list is loading.
- */
- void loadingStateUpdated(bool loading);
-
- void loadListFinished();
-
- void loadListFailed(QString msg);
-
-private:
- QList<PtrLWJGLVersion> m_vlist;
-
- QNetworkReply *m_netReply;
- QNetworkReply *reply;
-
- bool m_loading;
- bool m_errored;
- QString m_lastErrorMsg;
-
- void failed(QString msg);
-
- void finished();
-
- void setLoading(bool loading);
-
-private
-slots:
- virtual void netRequestComplete();
-};
diff --git a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp b/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp
deleted file mode 100644
index 25297fa4..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright 2013-2015 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 "LiteLoaderInstaller.h"
-
-#include <QJsonArray>
-#include <QJsonDocument>
-
-#include <QDebug>
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/Library.h"
-#include "minecraft/onesix/OneSixInstance.h"
-#include <minecraft/onesix/OneSixVersionFormat.h>
-#include "minecraft/liteloader/LiteLoaderVersionList.h"
-#include "Exception.h"
-
-LiteLoaderInstaller::LiteLoaderInstaller() : BaseInstaller()
-{
-}
-
-void LiteLoaderInstaller::prepare(LiteLoaderVersionPtr version)
-{
- m_version = version;
-}
-bool LiteLoaderInstaller::add(OneSixInstance *to)
-{
- if (!BaseInstaller::add(to))
- {
- return false;
- }
-
- QJsonObject obj;
-
- obj.insert("mainClass", QString("net.minecraft.launchwrapper.Launch"));
- obj.insert("+tweakers", QJsonArray::fromStringList(QStringList() << m_version->tweakClass));
- obj.insert("order", 10);
-
- QJsonArray libraries;
-
- for (auto Library : m_version->libraries)
- {
- libraries.append(OneSixVersionFormat::libraryToJson(Library.get()));
- }
-
- // liteloader
- {
- Library liteloaderLib("com.mumfrey:liteloader:" + m_version->version);
- liteloaderLib.setAbsoluteUrl(QString("http://dl.liteloader.com/versions/com/mumfrey/liteloader/%1/%2").arg(m_version->mcVersion, m_version->file));
- QJsonObject llLibObj = OneSixVersionFormat::libraryToJson(&liteloaderLib);
- libraries.append(llLibObj);
- }
-
- obj.insert("+libraries", libraries);
- obj.insert("name", QString("LiteLoader"));
- obj.insert("fileId", id());
- obj.insert("version", m_version->version);
- obj.insert("mcVersion", to->intendedVersionId());
-
- QFile file(filename(to->instanceRoot()));
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(QJsonDocument(obj).toJson());
- file.close();
-
- return true;
-}
-
-class LiteLoaderInstallTask : public Task
-{
- Q_OBJECT
-public:
- LiteLoaderInstallTask(LiteLoaderInstaller *installer, OneSixInstance *instance,
- BaseVersionPtr version, QObject *parent)
- : Task(parent), m_installer(installer), m_instance(instance), m_version(version)
- {
- }
-
-protected:
- void executeTask() override
- {
- LiteLoaderVersionPtr liteloaderVersion =
- std::dynamic_pointer_cast<LiteLoaderVersion>(m_version);
- if (!liteloaderVersion)
- {
- return;
- }
- m_installer->prepare(liteloaderVersion);
- if (!m_installer->add(m_instance))
- {
- emitFailed(tr("For reasons unknown, the LiteLoader installation failed. Check your "
- "MultiMC log files for details."));
- }
- else
- {
- try
- {
- m_instance->reloadProfile();
- emitSucceeded();
- }
- catch (Exception &e)
- {
- emitFailed(e.cause());
- }
- catch (...)
- {
- emitFailed(
- tr("Failed to load the version description file for reasons unknown."));
- }
- }
- }
-
-private:
- LiteLoaderInstaller *m_installer;
- OneSixInstance *m_instance;
- BaseVersionPtr m_version;
-};
-
-Task *LiteLoaderInstaller::createInstallTask(OneSixInstance *instance,
- BaseVersionPtr version,
- QObject *parent)
-{
- return new LiteLoaderInstallTask(this, instance, version, parent);
-}
-
-#include "LiteLoaderInstaller.moc"
diff --git a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h b/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h
deleted file mode 100644
index fe0aee3d..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderInstaller.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-#include <QMap>
-
-#include "BaseInstaller.h"
-#include "LiteLoaderVersionList.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT LiteLoaderInstaller : public BaseInstaller
-{
-public:
- LiteLoaderInstaller();
-
- void prepare(LiteLoaderVersionPtr version);
- bool add(OneSixInstance *to) override;
- virtual QString id() const override { return "com.mumfrey.liteloader"; }
-
- Task *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
-
-private:
- LiteLoaderVersionPtr m_version;
-};
diff --git a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp b/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp
deleted file mode 100644
index b0c9736a..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* Copyright 2013-2015 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 "LiteLoaderVersionList.h"
-#include <minecraft/onesix/OneSixVersionFormat.h>
-#include "Env.h"
-#include "net/URLConstants.h"
-#include "Exception.h"
-
-#include <QtXml>
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <QJsonParseError>
-
-#include <QtAlgorithms>
-
-#include <QtNetwork>
-
-LiteLoaderVersionList::LiteLoaderVersionList(QObject *parent) : BaseVersionList(parent)
-{
-}
-
-Task *LiteLoaderVersionList::getLoadTask()
-{
- return new LLListLoadTask(this);
-}
-
-bool LiteLoaderVersionList::isLoaded()
-{
- return m_loaded;
-}
-
-const BaseVersionPtr LiteLoaderVersionList::at(int i) const
-{
- return m_vlist.at(i);
-}
-
-int LiteLoaderVersionList::count() const
-{
- return m_vlist.count();
-}
-
-static bool cmpVersions(BaseVersionPtr first, BaseVersionPtr second)
-{
- auto left = std::dynamic_pointer_cast<LiteLoaderVersion>(first);
- auto right = std::dynamic_pointer_cast<LiteLoaderVersion>(second);
- return left->timestamp > right->timestamp;
-}
-
-void LiteLoaderVersionList::sortVersions()
-{
- beginResetModel();
- std::sort(m_vlist.begin(), m_vlist.end(), cmpVersions);
- endResetModel();
-}
-
-QVariant LiteLoaderVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<LiteLoaderVersion>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
-
- case VersionRole:
- return version->name();
-
- case VersionIdRole:
- return version->descriptor();
-
- case ParentGameVersionRole:
- return version->mcVersion;
-
- case RecommendedRole:
- return version->isLatest;
-
- default:
- return QVariant();
- }
-}
-
-QList<BaseVersionList::ModelRoles> LiteLoaderVersionList::providesRoles()
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole, RecommendedRole};
-}
-
-BaseVersionPtr LiteLoaderVersionList::getLatestStable() const
-{
- for (int i = 0; i < m_vlist.length(); i++)
- {
- auto ver = std::dynamic_pointer_cast<LiteLoaderVersion>(m_vlist.at(i));
- if (ver->isLatest)
- {
- return m_vlist.at(i);
- }
- }
- return BaseVersionPtr();
-}
-
-void LiteLoaderVersionList::updateListData(QList<BaseVersionPtr> versions)
-{
- beginResetModel();
- m_vlist = versions;
- m_loaded = true;
- std::sort(m_vlist.begin(), m_vlist.end(), cmpVersions);
- endResetModel();
-}
-
-LLListLoadTask::LLListLoadTask(LiteLoaderVersionList *vlist)
-{
- m_list = vlist;
-}
-
-LLListLoadTask::~LLListLoadTask()
-{
-}
-
-void LLListLoadTask::executeTask()
-{
- setStatus(tr("Loading LiteLoader version list..."));
- auto job = new NetJob("Version index");
- // we do not care if the version is stale or not.
- auto liteloaderEntry = ENV.metacache()->resolveEntry("liteloader", "versions.json");
-
- // verify by poking the server.
- liteloaderEntry->setStale(true);
-
- job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::LITELOADER_URL),
- liteloaderEntry));
-
- connect(listDownload.get(), SIGNAL(failed(int)), SLOT(listFailed()));
-
- listJob.reset(job);
- connect(listJob.get(), SIGNAL(succeeded()), SLOT(listDownloaded()));
- connect(listJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- listJob->start();
-}
-
-void LLListLoadTask::listFailed()
-{
- emitFailed("Failed to load LiteLoader version list.");
- return;
-}
-
-void LLListLoadTask::listDownloaded()
-{
- QByteArray data;
- {
- auto dlJob = listDownload;
- auto filename = std::dynamic_pointer_cast<CacheDownload>(dlJob)->getTargetFilepath();
- QFile listFile(filename);
- if (!listFile.open(QIODevice::ReadOnly))
- {
- emitFailed("Failed to open the LiteLoader version list.");
- return;
- }
- data = listFile.readAll();
- listFile.close();
- dlJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed("Error parsing version list JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isObject())
- {
- emitFailed("Error parsing version list JSON: jsonDoc is not an object");
- return;
- }
-
- const QJsonObject root = jsonDoc.object();
-
- // Now, get the array of versions.
- if (!root.value("versions").isObject())
- {
- emitFailed("Error parsing version list JSON: missing 'versions' object");
- return;
- }
-
- auto meta = root.value("meta").toObject();
- QString description = meta.value("description").toString(tr("This is a lightweight loader for mods that don't change game mechanics."));
- QString defaultUrl = meta.value("url").toString("http://dl.liteloader.com");
- QString authors = meta.value("authors").toString("Mumfrey");
- auto versions = root.value("versions").toObject();
-
- QList<BaseVersionPtr> tempList;
- for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt)
- {
- const QString mcVersion = vIt.key();
- QString latest;
- const QJsonObject artefacts = vIt.value()
- .toObject()
- .value("artefacts")
- .toObject()
- .value("com.mumfrey:liteloader")
- .toObject();
- QList<BaseVersionPtr> perMcVersionList;
- for (auto aIt = artefacts.begin(); aIt != artefacts.end(); ++aIt)
- {
- const QString identifier = aIt.key();
- const QJsonObject artefact = aIt.value().toObject();
- if (identifier == "latest")
- {
- latest = artefact.value("version").toString();
- continue;
- }
- LiteLoaderVersionPtr version(new LiteLoaderVersion());
- version->version = artefact.value("version").toString();
- version->file = artefact.value("file").toString();
- version->mcVersion = mcVersion;
- version->md5 = artefact.value("md5").toString();
- version->timestamp = artefact.value("timestamp").toString().toInt();
- version->tweakClass = artefact.value("tweakClass").toString();
- version->authors = authors;
- version->description = description;
- version->defaultUrl = defaultUrl;
- const QJsonArray libs = artefact.value("libraries").toArray();
- for (auto lIt = libs.begin(); lIt != libs.end(); ++lIt)
- {
- auto libobject = (*lIt).toObject();
- try
- {
- auto lib = OneSixVersionFormat::libraryFromJson(libobject, "versions.json");
- // hack to make liteloader 1.7.10_00 work
- if(lib->rawName() == GradleSpecifier("org.ow2.asm:asm-all:5.0.3"))
- {
- lib->setRepositoryURL("http://repo.maven.apache.org/maven2/");
- }
- version->libraries.append(lib);
- }
- catch (Exception &e)
- {
- qCritical() << "Couldn't read JSON object:";
- continue;
- }
- }
- perMcVersionList.append(version);
- }
- for (auto version : perMcVersionList)
- {
- auto v = std::dynamic_pointer_cast<LiteLoaderVersion>(version);
- v->isLatest = v->version == latest;
- }
- tempList.append(perMcVersionList);
- }
- m_list->updateListData(tempList);
-
- emitSucceeded();
-}
diff --git a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h b/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h
deleted file mode 100644
index 1dba4b6a..00000000
--- a/libraries/logic/minecraft/liteloader/LiteLoaderVersionList.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-
-#include <QString>
-#include <QStringList>
-#include "BaseVersion.h"
-#include "BaseVersionList.h"
-#include "tasks/Task.h"
-#include "net/NetJob.h"
-#include <minecraft/Library.h>
-
-#include "multimc_logic_export.h"
-
-class LLListLoadTask;
-class QNetworkReply;
-
-class LiteLoaderVersion : public BaseVersion
-{
-public:
- QString descriptor() override
- {
- if (isLatest)
- {
- return QObject::tr("Latest");
- }
- return QString();
- }
- QString typeString() const override
- {
- return mcVersion;
- }
- QString name() override
- {
- return version;
- }
-
- // important info
- QString version;
- QString file;
- QString mcVersion;
- QString md5;
- int timestamp;
- bool isLatest;
- QString tweakClass;
- QList<LibraryPtr> libraries;
-
- // meta
- QString defaultUrl;
- QString description;
- QString authors;
-};
-typedef std::shared_ptr<LiteLoaderVersion> LiteLoaderVersionPtr;
-
-class MULTIMC_LOGIC_EXPORT LiteLoaderVersionList : public BaseVersionList
-{
- Q_OBJECT
-public:
- friend class LLListLoadTask;
-
- explicit LiteLoaderVersionList(QObject *parent = 0);
-
- virtual Task *getLoadTask();
- virtual bool isLoaded();
- virtual const BaseVersionPtr at(int i) const;
- virtual int count() const;
- virtual void sortVersions();
- virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
- virtual QList< ModelRoles > providesRoles();
-
- virtual BaseVersionPtr getLatestStable() const;
-
-protected:
- QList<BaseVersionPtr> m_vlist;
-
- bool m_loaded = false;
-
-protected
-slots:
- virtual void updateListData(QList<BaseVersionPtr> versions);
-};
-
-class LLListLoadTask : public Task
-{
- Q_OBJECT
-
-public:
- explicit LLListLoadTask(LiteLoaderVersionList *vlist);
- ~LLListLoadTask();
-
- virtual void executeTask();
-
-protected
-slots:
- void listDownloaded();
- void listFailed();
-
-protected:
- NetJobPtr listJob;
- CacheDownloadPtr listDownload;
- LiteLoaderVersionList *m_list;
-};
-
-Q_DECLARE_METATYPE(LiteLoaderVersionPtr)
diff --git a/libraries/logic/minecraft/onesix/OneSixInstance.cpp b/libraries/logic/minecraft/onesix/OneSixInstance.cpp
deleted file mode 100644
index 258e26c5..00000000
--- a/libraries/logic/minecraft/onesix/OneSixInstance.cpp
+++ /dev/null
@@ -1,597 +0,0 @@
-/* Copyright 2013-2015 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 <QDebug>
-#include <Env.h>
-
-#include "OneSixInstance.h"
-#include "OneSixUpdate.h"
-#include "OneSixProfileStrategy.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/VersionBuildError.h"
-#include "launch/LaunchTask.h"
-#include "launch/steps/PreLaunchCommand.h"
-#include "launch/steps/Update.h"
-#include "launch/steps/LaunchMinecraft.h"
-#include "launch/steps/PostLaunchCommand.h"
-#include "launch/steps/TextPrint.h"
-#include "launch/steps/ModMinecraftJar.h"
-#include "launch/steps/CheckJava.h"
-#include "MMCZip.h"
-
-#include "minecraft/AssetsUtils.h"
-#include "minecraft/WorldList.h"
-#include <FileSystem.h>
-
-OneSixInstance::OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : MinecraftInstance(globalSettings, settings, rootDir)
-{
- m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
-}
-
-void OneSixInstance::init()
-{
- createProfile();
-}
-
-void OneSixInstance::createProfile()
-{
- m_profile.reset(new MinecraftProfile(new OneSixProfileStrategy(this)));
-}
-
-QSet<QString> OneSixInstance::traits()
-{
- auto version = getMinecraftProfile();
- if (!version)
- {
- return {"version-incomplete"};
- }
- else
- {
- return version->getTraits();
- }
-}
-
-std::shared_ptr<Task> OneSixInstance::createUpdateTask()
-{
- return std::shared_ptr<Task>(new OneSixUpdate(this));
-}
-
-QString replaceTokensIn(QString text, QMap<QString, QString> with)
-{
- QString result;
- QRegExp token_regexp("\\$\\{(.+)\\}");
- token_regexp.setMinimal(true);
- QStringList list;
- int tail = 0;
- int head = 0;
- while ((head = token_regexp.indexIn(text, head)) != -1)
- {
- result.append(text.mid(tail, head - tail));
- QString key = token_regexp.cap(1);
- auto iter = with.find(key);
- if (iter != with.end())
- {
- result.append(*iter);
- }
- head += token_regexp.matchedLength();
- tail = head;
- }
- result.append(text.mid(tail));
- return result;
-}
-
-QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
-{
- QString args_pattern = m_profile->getMinecraftArguments();
- for (auto tweaker : m_profile->getTweakers())
- {
- args_pattern += " --tweakClass " + tweaker;
- }
-
- QMap<QString, QString> token_mapping;
- // yggdrasil!
- token_mapping["auth_username"] = session->username;
- token_mapping["auth_session"] = session->session;
- token_mapping["auth_access_token"] = session->access_token;
- token_mapping["auth_player_name"] = session->player_name;
- token_mapping["auth_uuid"] = session->uuid;
-
- // blatant self-promotion.
- token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
- if(m_profile->isVanilla())
- {
- token_mapping["version_type"] = m_profile->getMinecraftVersionType();
- }
- else
- {
- token_mapping["version_type"] = "custom";
- }
-
- QString absRootDir = QDir(minecraftRoot()).absolutePath();
- token_mapping["game_directory"] = absRootDir;
- QString absAssetsDir = QDir("assets/").absolutePath();
- auto assets = m_profile->getMinecraftAssets();
- token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
-
- token_mapping["user_properties"] = session->serializeUserProperties();
- token_mapping["user_type"] = session->user_type;
-
- // 1.7.3+ assets tokens
- token_mapping["assets_root"] = absAssetsDir;
- token_mapping["assets_index_name"] = assets->id;
-
- QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
- for (int i = 0; i < parts.length(); i++)
- {
- parts[i] = replaceTokensIn(parts[i], token_mapping);
- }
- return parts;
-}
-
-QString OneSixInstance::createLaunchScript(AuthSessionPtr session)
-{
- QString launchScript;
-
- if (!m_profile)
- return nullptr;
-
- for(auto & mod: loaderModList()->allMods())
- {
- if(!mod.enabled())
- continue;
- if(mod.type() == Mod::MOD_FOLDER)
- continue;
- // TODO: proper implementation would need to descend into folders.
-
- launchScript += "mod " + mod.filename().completeBaseName() + "\n";;
- }
-
- for(auto & coremod: coreModList()->allMods())
- {
- if(!coremod.enabled())
- continue;
- if(coremod.type() == Mod::MOD_FOLDER)
- continue;
- // TODO: proper implementation would need to descend into folders.
-
- launchScript += "coremod " + coremod.filename().completeBaseName() + "\n";;
- }
-
- for(auto & jarmod: m_profile->getJarMods())
- {
- launchScript += "jarmod " + jarmod->originalName + " (" + jarmod->name + ")\n";
- }
-
- auto mainClass = m_profile->getMainClass();
- if (!mainClass.isEmpty())
- {
- launchScript += "mainClass " + mainClass + "\n";
- }
- auto appletClass = m_profile->getAppletClass();
- if (!appletClass.isEmpty())
- {
- launchScript += "appletClass " + appletClass + "\n";
- }
-
- // generic minecraft params
- for (auto param : processMinecraftArgs(session))
- {
- launchScript += "param " + param + "\n";
- }
-
- // window size, title and state, legacy
- {
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- windowParams = "max";
- else
- windowParams = QString("%1x%2")
- .arg(settings()->get("MinecraftWinWidth").toInt())
- .arg(settings()->get("MinecraftWinHeight").toInt());
- launchScript += "windowTitle " + windowTitle() + "\n";
- launchScript += "windowParams " + windowParams + "\n";
- }
-
- // legacy auth
- {
- launchScript += "userName " + session->player_name + "\n";
- launchScript += "sessionId " + session->session + "\n";
- }
-
- // libraries and class path.
- {
- auto libs = m_profile->getLibraries();
-
- QStringList jar, native, native32, native64;
- for (auto lib : libs)
- {
- lib->getApplicableFiles(currentSystem, jar, native, native32, native64);
- }
- for(auto file: jar)
- {
- launchScript += "cp " + file + "\n";
- }
- for(auto file: native)
- {
- launchScript += "ext " + file + "\n";
- }
- for(auto file: native32)
- {
- launchScript += "ext32 " + file + "\n";
- }
- for(auto file: native64)
- {
- launchScript += "ext64 " + file + "\n";
- }
- QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
- launchScript += "natives " + natives_dir.absolutePath() + "\n";
- auto jarMods = getJarMods();
- if (!jarMods.isEmpty())
- {
- launchScript += "cp " + QDir(instanceRoot()).absoluteFilePath("minecraft.jar") + "\n";
- }
- else
- {
- QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar";
- launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n";
- }
- }
-
- // traits. including legacyLaunch and others ;)
- for (auto trait : m_profile->getTraits())
- {
- launchScript += "traits " + trait + "\n";
- }
- launchScript += "launcher onesix\n";
- return launchScript;
-}
-
-std::shared_ptr<LaunchTask> OneSixInstance::createLaunchTask(AuthSessionPtr session)
-{
- auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
- auto pptr = process.get();
-
- // print a header
- {
- process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
- }
- {
- auto step = std::make_shared<CheckJava>(pptr);
- process->appendStep(step);
- }
- // run pre-launch command if that's needed
- if(getPreLaunchCommand().size())
- {
- auto step = std::make_shared<PreLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- // if we aren't in offline mode,.
- if(session->status != AuthSession::PlayableOffline)
- {
- process->appendStep(std::make_shared<Update>(pptr));
- }
- // if there are any jar mods
- if(getJarMods().size())
- {
- auto step = std::make_shared<ModMinecraftJar>(pptr);
- process->appendStep(step);
- }
- // actually launch the game
- {
- auto step = std::make_shared<LaunchMinecraft>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- step->setAuthSession(session);
- process->appendStep(step);
- }
- // run post-exit command if that's needed
- if(getPostExitCommand().size())
- {
- auto step = std::make_shared<PostLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- if (session)
- {
- process->setCensorFilter(createCensorFilterFromSession(session));
- }
- return process;
-}
-
-std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
-{
- class JarModTask : public Task
- {
- public:
- explicit JarModTask(std::shared_ptr<OneSixInstance> inst) : Task(nullptr), m_inst(inst)
- {
- }
- virtual void executeTask()
- {
- auto profile = m_inst->getMinecraftProfile();
- // nuke obsolete stripped jar(s) if needed
- QString version_id = profile->getMinecraftVersion();
- QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
- QFile strippedJar(strippedPath);
- if(strippedJar.exists())
- {
- strippedJar.remove();
- }
- auto tempJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("temp.jar");
- QFile tempJar(tempJarPath);
- if(tempJar.exists())
- {
- tempJar.remove();
- }
- auto finalJarPath = QDir(m_inst->instanceRoot()).absoluteFilePath("minecraft.jar");
- QFile finalJar(finalJarPath);
- if(finalJar.exists())
- {
- if(!finalJar.remove())
- {
- emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
- return;
- }
- }
-
- // create temporary modded jar, if needed
- auto jarMods = m_inst->getJarMods();
- if(jarMods.size())
- {
- auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version_id + "/" + version_id + ".jar");
- QString localPath = version_id + "/" + version_id + ".jar";
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", localPath);
- QString fullJarPath = entry->getFullPath();
- if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
- {
- emitFailed(tr("Failed to create the custom Minecraft jar file."));
- return;
- }
- }
- emitSucceeded();
- }
- std::shared_ptr<OneSixInstance> m_inst;
- };
- return std::make_shared<JarModTask>(std::dynamic_pointer_cast<OneSixInstance>(shared_from_this()));
-}
-
-void OneSixInstance::cleanupAfterRun()
-{
- QString target_dir = FS::PathCombine(instanceRoot(), "natives/");
- QDir dir(target_dir);
- dir.removeRecursively();
-}
-
-std::shared_ptr<ModList> OneSixInstance::loaderModList() const
-{
- if (!m_loader_mod_list)
- {
- m_loader_mod_list.reset(new ModList(loaderModsDir()));
- }
- m_loader_mod_list->update();
- return m_loader_mod_list;
-}
-
-std::shared_ptr<ModList> OneSixInstance::coreModList() const
-{
- if (!m_core_mod_list)
- {
- m_core_mod_list.reset(new ModList(coreModsDir()));
- }
- m_core_mod_list->update();
- return m_core_mod_list;
-}
-
-std::shared_ptr<ModList> OneSixInstance::resourcePackList() const
-{
- if (!m_resource_pack_list)
- {
- m_resource_pack_list.reset(new ModList(resourcePacksDir()));
- }
- m_resource_pack_list->update();
- return m_resource_pack_list;
-}
-
-std::shared_ptr<ModList> OneSixInstance::texturePackList() const
-{
- if (!m_texture_pack_list)
- {
- m_texture_pack_list.reset(new ModList(texturePacksDir()));
- }
- m_texture_pack_list->update();
- return m_texture_pack_list;
-}
-
-std::shared_ptr<WorldList> OneSixInstance::worldList() const
-{
- if (!m_world_list)
- {
- m_world_list.reset(new WorldList(worldDir()));
- }
- return m_world_list;
-}
-
-bool OneSixInstance::setIntendedVersionId(QString version)
-{
- settings()->set("IntendedVersion", version);
- if(getMinecraftProfile())
- {
- clearProfile();
- }
- emit propertiesChanged(this);
- return true;
-}
-
-QList< Mod > OneSixInstance::getJarMods() const
-{
- QList<Mod> mods;
- for (auto jarmod : m_profile->getJarMods())
- {
- QString filePath = jarmodsPath().absoluteFilePath(jarmod->name);
- mods.push_back(Mod(QFileInfo(filePath)));
- }
- return mods;
-}
-
-
-QString OneSixInstance::intendedVersionId() const
-{
- return settings()->get("IntendedVersion").toString();
-}
-
-void OneSixInstance::setShouldUpdate(bool)
-{
-}
-
-bool OneSixInstance::shouldUpdate() const
-{
- return true;
-}
-
-QString OneSixInstance::currentVersionId() const
-{
- return intendedVersionId();
-}
-
-void OneSixInstance::reloadProfile()
-{
- m_profile->reload();
- auto severity = m_profile->getProblemSeverity();
- if(severity == ProblemSeverity::PROBLEM_ERROR)
- {
- setFlag(VersionBrokenFlag);
- }
- else
- {
- unsetFlag(VersionBrokenFlag);
- }
- emit versionReloaded();
-}
-
-void OneSixInstance::clearProfile()
-{
- m_profile->clear();
- emit versionReloaded();
-}
-
-std::shared_ptr<MinecraftProfile> OneSixInstance::getMinecraftProfile() const
-{
- return m_profile;
-}
-
-QDir OneSixInstance::librariesPath() const
-{
- return QDir::current().absoluteFilePath("libraries");
-}
-
-QDir OneSixInstance::jarmodsPath() const
-{
- return QDir(jarModsDir());
-}
-
-QDir OneSixInstance::versionsPath() const
-{
- return QDir::current().absoluteFilePath("versions");
-}
-
-bool OneSixInstance::providesVersionFile() const
-{
- return false;
-}
-
-bool OneSixInstance::reload()
-{
- if (BaseInstance::reload())
- {
- try
- {
- reloadProfile();
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- return false;
-}
-
-QString OneSixInstance::loaderModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "mods");
-}
-
-QString OneSixInstance::coreModsDir() const
-{
- return FS::PathCombine(minecraftRoot(), "coremods");
-}
-
-QString OneSixInstance::resourcePacksDir() const
-{
- return FS::PathCombine(minecraftRoot(), "resourcepacks");
-}
-
-QString OneSixInstance::texturePacksDir() const
-{
- return FS::PathCombine(minecraftRoot(), "texturepacks");
-}
-
-QString OneSixInstance::instanceConfigFolder() const
-{
- return FS::PathCombine(minecraftRoot(), "config");
-}
-
-QString OneSixInstance::jarModsDir() const
-{
- return FS::PathCombine(instanceRoot(), "jarmods");
-}
-
-QString OneSixInstance::libDir() const
-{
- return FS::PathCombine(minecraftRoot(), "lib");
-}
-
-QString OneSixInstance::worldDir() const
-{
- return FS::PathCombine(minecraftRoot(), "saves");
-}
-
-QStringList OneSixInstance::extraArguments() const
-{
- auto list = BaseInstance::extraArguments();
- auto version = getMinecraftProfile();
- if (!version)
- return list;
- auto jarMods = getJarMods();
- if (!jarMods.isEmpty())
- {
- list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
- "-Dfml.ignorePatchDiscrepancies=true"});
- }
- return list;
-}
-
-std::shared_ptr<OneSixInstance> OneSixInstance::getSharedPtr()
-{
- return std::dynamic_pointer_cast<OneSixInstance>(BaseInstance::getSharedPtr());
-}
-
-QString OneSixInstance::typeName() const
-{
- return tr("OneSix");
-}
diff --git a/libraries/logic/minecraft/onesix/OneSixInstance.h b/libraries/logic/minecraft/onesix/OneSixInstance.h
deleted file mode 100644
index 2dfab48c..00000000
--- a/libraries/logic/minecraft/onesix/OneSixInstance.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "minecraft/MinecraftInstance.h"
-
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/ModList.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT OneSixInstance : public MinecraftInstance
-{
- Q_OBJECT
-public:
- explicit OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~OneSixInstance(){};
-
- virtual void init() override;
-
- ////// Mod Lists //////
- std::shared_ptr<ModList> loaderModList() const;
- std::shared_ptr<ModList> coreModList() const;
- std::shared_ptr<ModList> resourcePackList() const override;
- std::shared_ptr<ModList> texturePackList() const override;
- std::shared_ptr<WorldList> worldList() const override;
- virtual QList<Mod> getJarMods() const override;
- virtual void createProfile();
-
- virtual QSet<QString> traits() override;
-
- ////// Directories and files //////
- QString jarModsDir() const;
- QString resourcePacksDir() const;
- QString texturePacksDir() const;
- QString loaderModsDir() const;
- QString coreModsDir() const;
- QString libDir() const;
- QString worldDir() const;
- virtual QString instanceConfigFolder() const override;
-
- virtual std::shared_ptr<Task> createUpdateTask() override;
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
- virtual std::shared_ptr<Task> createJarModdingTask() override;
-
- virtual QString createLaunchScript(AuthSessionPtr session) override;
-
- virtual void cleanupAfterRun() override;
-
- virtual QString intendedVersionId() const override;
- virtual bool setIntendedVersionId(QString version) override;
-
- virtual QString currentVersionId() const override;
-
- virtual bool shouldUpdate() const override;
- virtual void setShouldUpdate(bool val) override;
-
- /**
- * reload the profile, including version json files.
- *
- * throws various exceptions :3
- */
- void reloadProfile();
-
- /// clears all version information in preparation for an update
- void clearProfile();
-
- /// get the current full version info
- std::shared_ptr<MinecraftProfile> getMinecraftProfile() const;
-
- virtual QDir jarmodsPath() const;
- virtual QDir librariesPath() const;
- virtual QDir versionsPath() const;
- virtual bool providesVersionFile() const;
-
- bool reload() override;
-
- virtual QStringList extraArguments() const override;
-
- std::shared_ptr<OneSixInstance> getSharedPtr();
-
- virtual QString typeName() const override;
-
- bool canExport() const override
- {
- return true;
- }
-
-signals:
- void versionReloaded();
-
-private:
- QStringList processMinecraftArgs(AuthSessionPtr account);
-
-protected:
- std::shared_ptr<MinecraftProfile> m_profile;
- mutable std::shared_ptr<ModList> m_loader_mod_list;
- mutable std::shared_ptr<ModList> m_core_mod_list;
- mutable std::shared_ptr<ModList> m_resource_pack_list;
- mutable std::shared_ptr<ModList> m_texture_pack_list;
- mutable std::shared_ptr<WorldList> m_world_list;
-};
-
-Q_DECLARE_METATYPE(std::shared_ptr<OneSixInstance>)
diff --git a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp
deleted file mode 100644
index af42286d..00000000
--- a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-#include "OneSixProfileStrategy.h"
-#include "OneSixInstance.h"
-#include "OneSixVersionFormat.h"
-
-#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
-#include "Env.h"
-#include <FileSystem.h>
-
-#include <QDir>
-#include <QUuid>
-#include <QJsonDocument>
-#include <QJsonArray>
-
-OneSixProfileStrategy::OneSixProfileStrategy(OneSixInstance* instance)
-{
- m_instance = instance;
-}
-
-void OneSixProfileStrategy::upgradeDeprecatedFiles()
-{
- auto versionJsonPath = FS::PathCombine(m_instance->instanceRoot(), "version.json");
- auto customJsonPath = FS::PathCombine(m_instance->instanceRoot(), "custom.json");
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
-
- QString sourceFile;
- QString renameFile;
-
- // convert old crap.
- if(QFile::exists(customJsonPath))
- {
- sourceFile = customJsonPath;
- renameFile = versionJsonPath;
- }
- else if(QFile::exists(versionJsonPath))
- {
- sourceFile = versionJsonPath;
- }
- if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
- {
- if(!FS::ensureFilePathExists(mcJson))
- {
- qWarning() << "Couldn't create patches folder for" << m_instance->name();
- return;
- }
- if(!renameFile.isEmpty() && QFile::exists(renameFile))
- {
- if(!QFile::rename(renameFile, renameFile + ".old"))
- {
- qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << m_instance->name();
- return;
- }
- }
- auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
- ProfileUtils::removeLwjglFromPatch(file);
- file->fileId = "net.minecraft";
- file->version = file->minecraftVersion;
- file->name = "Minecraft";
- auto data = OneSixVersionFormat::versionFileToJson(file, false).toJson();
- QSaveFile newPatchFile(mcJson);
- if(!newPatchFile.open(QIODevice::WriteOnly))
- {
- newPatchFile.cancelWriting();
- qWarning() << "Couldn't open main patch for writing in" << m_instance->name();
- return;
- }
- newPatchFile.write(data);
- if(!newPatchFile.commit())
- {
- qWarning() << "Couldn't save main patch in" << m_instance->name();
- return;
- }
- if(!QFile::rename(sourceFile, sourceFile + ".old"))
- {
- qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << m_instance->name();
- return;
- }
- }
-}
-
-void OneSixProfileStrategy::loadDefaultBuiltinPatches()
-{
- {
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
- // load up the base minecraft patch
- ProfilePatchPtr minecraftPatch;
- if(QFile::exists(mcJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
- if(file->version.isEmpty())
- {
- file->version = m_instance->intendedVersionId();
- }
- file->setVanilla(false);
- file->setRevertible(true);
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- auto mcversion = ENV.getVersion("net.minecraft", m_instance->intendedVersionId());
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(mcversion);
- }
- if (!minecraftPatch)
- {
- throw VersionIncomplete("net.minecraft");
- }
- minecraftPatch->setOrder(-2);
- profile->appendPatch(minecraftPatch);
- }
-
- {
- auto lwjglJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "org.lwjgl.json");
- ProfilePatchPtr lwjglPatch;
- if(QFile::exists(lwjglJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(lwjglJson), false);
- file->setVanilla(false);
- file->setRevertible(true);
- lwjglPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
- {
- // NOTE: this is obviously fake, is fixed in unstable.
- QResource LWJGL(":/versions/LWJGL/2.9.1.json");
- auto lwjgl = ProfileUtils::parseJsonFile(LWJGL.absoluteFilePath(), false);
- lwjgl->setVanilla(true);
- lwjgl->setCustomizable(true);
- lwjglPatch = std::dynamic_pointer_cast<ProfilePatch>(lwjgl);
- }
- if (!lwjglPatch)
- {
- throw VersionIncomplete("org.lwjgl");
- }
- lwjglPatch->setOrder(-1);
- profile->appendPatch(lwjglPatch);
- }
-}
-
-void OneSixProfileStrategy::loadUserPatches()
-{
- // load all patches, put into map for ordering, apply in the right order
- ProfileUtils::PatchOrder userOrder;
- ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
- QDir patches(FS::PathCombine(m_instance->instanceRoot(),"patches"));
- QSet<QString> seen_extra;
-
- // first, load things by sort order.
- for (auto id : userOrder)
- {
- // ignore builtins
- if (id == "net.minecraft")
- continue;
- if (id == "org.lwjgl")
- continue;
- // parse the file
- QString filename = patches.absoluteFilePath(id + ".json");
- QFileInfo finfo(filename);
- if(!finfo.exists())
- {
- qDebug() << "Patch file " << filename << " was deleted by external means...";
- continue;
- }
- qDebug() << "Reading" << filename << "by user order";
- VersionFilePtr file = ProfileUtils::parseJsonFile(finfo, false);
- // sanity check. prevent tampering with files.
- if (file->fileId != id)
- {
- file->addProblem(PROBLEM_WARNING, QObject::tr("load id %1 does not match internal id %2").arg(id, file->fileId));
- seen_extra.insert(file->fileId);
- }
- file->setRemovable(true);
- file->setMovable(true);
- profile->appendPatch(file);
- }
- // now load the rest by internal preference.
- QMultiMap<int, VersionFilePtr> files;
- for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files))
- {
- // parse the file
- qDebug() << "Reading" << info.fileName();
- auto file = ProfileUtils::parseJsonFile(info, true);
- // ignore builtins
- if (file->fileId == "net.minecraft")
- continue;
- if (file->fileId == "org.lwjgl")
- continue;
- // do not load versions with broken IDs twice
- if(seen_extra.contains(file->fileId))
- continue;
- // do not load what we already loaded in the first pass
- if (userOrder.contains(file->fileId))
- continue;
- file->setRemovable(true);
- file->setMovable(true);
- files.insert(file->order, file);
- }
- QSet<int> seen;
- for (auto order : files.keys())
- {
- if(seen.contains(order))
- continue;
- seen.insert(order);
- const auto &values = files.values(order);
- if(values.size() == 1)
- {
- profile->appendPatch(values[0]);
- continue;
- }
- for(auto &file: values)
- {
- QStringList list;
- for(auto &file2: values)
- {
- if(file != file2)
- list.append(file2->name);
- }
- file->addProblem(PROBLEM_WARNING, QObject::tr("%1 has the same order as the following components:\n%2").arg(file->name, list.join(", ")));
- profile->appendPatch(file);
- }
- }
-}
-
-
-void OneSixProfileStrategy::load()
-{
- profile->clearPatches();
-
- upgradeDeprecatedFiles();
- loadDefaultBuiltinPatches();
- loadUserPatches();
-}
-
-bool OneSixProfileStrategy::saveOrder(ProfileUtils::PatchOrder order)
-{
- return ProfileUtils::writeOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), order);
-}
-
-bool OneSixProfileStrategy::resetOrder()
-{
- return QDir(m_instance->instanceRoot()).remove("order.json");
-}
-
-bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
-{
- bool ok = true;
- // first, remove the patch file. this ensures it's not used anymore
- auto fileName = patch->getFilename();
- if(fileName.size())
- {
- QFile patchFile(fileName);
- if(patchFile.exists() && !patchFile.remove())
- {
- qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
- return false;
- }
- }
-
-
- auto preRemoveJarMod = [&](JarmodPtr jarMod) -> bool
- {
- QString fullpath = FS::PathCombine(m_instance->jarModsDir(), jarMod->name);
- QFileInfo finfo (fullpath);
- if(finfo.exists())
- {
- QFile jarModFile(fullpath);
- if(!jarModFile.remove())
- {
- qCritical() << "File" << fullpath << "could not be removed because:" << jarModFile.errorString();
- return false;
- }
- return true;
- }
- return true;
- };
-
- for(auto &jarmod: patch->getJarMods())
- {
- ok &= preRemoveJarMod(jarmod);
- }
- return ok;
-}
-
-bool OneSixProfileStrategy::customizePatch(ProfilePatchPtr patch)
-{
- if(patch->isCustom())
- {
- return false;
- }
-
- auto filename = FS::PathCombine(m_instance->instanceRoot(), "patches" , patch->getID() + ".json");
- if(!FS::ensureFilePathExists(filename))
- {
- return false;
- }
- try
- {
- QSaveFile jsonFile(filename);
- if(!jsonFile.open(QIODevice::WriteOnly))
- {
- return false;
- }
- auto vfile = patch->getVersionFile();
- if(!vfile)
- {
- return false;
- }
- auto document = OneSixVersionFormat::versionFileToJson(vfile, true);
- jsonFile.write(document.toJson());
- if(!jsonFile.commit())
- {
- return false;
- }
- load();
- }
- catch (VersionIncomplete &error)
- {
- qDebug() << "Version was incomplete:" << error.cause();
- }
- catch (Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return true;
-}
-
-bool OneSixProfileStrategy::revertPatch(ProfilePatchPtr patch)
-{
- if(!patch->isCustom())
- {
- // already not custom
- return true;
- }
- auto filename = patch->getFilename();
- if(!QFile::exists(filename))
- {
- // already gone / not custom
- return true;
- }
- // just kill the file and reload
- bool result = QFile::remove(filename);
- try
- {
- load();
- }
- catch (VersionIncomplete &error)
- {
- qDebug() << "Version was incomplete:" << error.cause();
- }
- catch (Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return result;
-}
-
-bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
-{
- QString patchDir = FS::PathCombine(m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
-
- if (!FS::ensureFolderPathExists(m_instance->jarModsDir()))
- {
- return false;
- }
-
- for(auto filepath:filepaths)
- {
- QFileInfo sourceInfo(filepath);
- auto uuid = QUuid::createUuid();
- QString id = uuid.toString().remove('{').remove('}');
- QString target_filename = id + ".jar";
- QString target_id = "org.multimc.jarmod." + id;
- QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
- QString finalPath = FS::PathCombine(m_instance->jarModsDir(), target_filename);
-
- QFileInfo targetInfo(finalPath);
- if(targetInfo.exists())
- {
- return false;
- }
-
- if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
- {
- return false;
- }
-
- auto f = std::make_shared<VersionFile>();
- auto jarMod = std::make_shared<Jarmod>();
- jarMod->name = target_filename;
- jarMod->originalName = sourceInfo.completeBaseName();
- f->jarMods.append(jarMod);
- f->name = target_name;
- f->fileId = target_id;
- f->order = profile->getFreeOrderNumber();
- QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
- f->filename = patchFileName;
- f->setMovable(true);
- f->setRemovable(true);
-
- QFile file(patchFileName);
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
- file.close();
- profile->appendPatch(f);
- }
- profile->saveCurrentOrder();
- profile->reapplyPatches();
- return true;
-}
-
diff --git a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.h b/libraries/logic/minecraft/onesix/OneSixProfileStrategy.h
deleted file mode 100644
index 96c1ba7b..00000000
--- a/libraries/logic/minecraft/onesix/OneSixProfileStrategy.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-#include "minecraft/ProfileStrategy.h"
-
-class OneSixInstance;
-
-class OneSixProfileStrategy : public ProfileStrategy
-{
-public:
- OneSixProfileStrategy(OneSixInstance * instance);
- virtual ~OneSixProfileStrategy() {};
- virtual void load() override;
- virtual bool resetOrder() override;
- virtual bool saveOrder(ProfileUtils::PatchOrder order) override;
- virtual bool installJarMods(QStringList filepaths) override;
- virtual bool removePatch(ProfilePatchPtr patch) override;
- virtual bool customizePatch(ProfilePatchPtr patch) override;
- virtual bool revertPatch(ProfilePatchPtr patch) override;
-
-protected:
- virtual void loadDefaultBuiltinPatches();
- virtual void loadUserPatches();
- void upgradeDeprecatedFiles();
-
-protected:
- OneSixInstance *m_instance;
-};
diff --git a/libraries/logic/minecraft/onesix/OneSixUpdate.cpp b/libraries/logic/minecraft/onesix/OneSixUpdate.cpp
deleted file mode 100644
index 1c2cd196..00000000
--- a/libraries/logic/minecraft/onesix/OneSixUpdate.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/* Copyright 2013-2015 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 "Env.h"
-#include <minecraft/forge/ForgeXzDownload.h>
-#include "OneSixUpdate.h"
-#include "OneSixInstance.h"
-
-#include <QtNetwork>
-
-#include <QFile>
-#include <QFileInfo>
-#include <QTextStream>
-#include <QDataStream>
-#include <JlCompress.h>
-
-#include "BaseInstance.h"
-#include "minecraft/MinecraftVersionList.h"
-#include "minecraft/MinecraftProfile.h"
-#include "minecraft/Library.h"
-#include "net/URLConstants.h"
-#include "minecraft/AssetsUtils.h"
-#include "Exception.h"
-#include "MMCZip.h"
-#include <FileSystem.h>
-
-OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
-{
-}
-
-void OneSixUpdate::executeTask()
-{
- // Make directories
- QDir mcDir(m_inst->minecraftRoot());
- if (!mcDir.exists() && !mcDir.mkpath("."))
- {
- emitFailed(tr("Failed to create folder for minecraft binaries."));
- return;
- }
-
- // Get a pointer to the version object that corresponds to the instance's version.
- targetVersion = std::dynamic_pointer_cast<MinecraftVersion>(ENV.getVersion("net.minecraft", m_inst->intendedVersionId()));
- if (targetVersion == nullptr)
- {
- // don't do anything if it was invalid
- emitFailed(tr("The specified Minecraft version is invalid. Choose a different one."));
- return;
- }
- if (m_inst->providesVersionFile() || !targetVersion->needsUpdate())
- {
- qDebug() << "Instance either provides a version file or doesn't need an update.";
- jarlibStart();
- return;
- }
- versionUpdateTask = std::dynamic_pointer_cast<MinecraftVersionList>(ENV.getVersionList("net.minecraft"))->createUpdateTask(m_inst->intendedVersionId());
- if (!versionUpdateTask)
- {
- qDebug() << "Didn't spawn an update task.";
- jarlibStart();
- return;
- }
- connect(versionUpdateTask.get(), SIGNAL(succeeded()), SLOT(jarlibStart()));
- connect(versionUpdateTask.get(), &NetJob::failed, this, &OneSixUpdate::versionUpdateFailed);
- connect(versionUpdateTask.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- setStatus(tr("Getting the version files from Mojang..."));
- versionUpdateTask->start();
-}
-
-void OneSixUpdate::versionUpdateFailed(QString reason)
-{
- emitFailed(reason);
-}
-
-void OneSixUpdate::assetIndexStart()
-{
- setStatus(tr("Updating assets index..."));
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto profile = inst->getMinecraftProfile();
- auto assets = profile->getMinecraftAssets();
- QUrl indexUrl = assets->url;
- QString localPath = assets->id + ".json";
- auto job = new NetJob(tr("Asset index for %1").arg(inst->name()));
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", localPath);
- entry->setStale(true);
- job->addNetAction(CacheDownload::make(indexUrl, entry));
- jarlibDownloadJob.reset(job);
-
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetIndexFinished()));
- connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetIndexFailed);
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
-
- qDebug() << m_inst->name() << ": Starting asset index download";
- jarlibDownloadJob->start();
-}
-
-void OneSixUpdate::assetIndexFinished()
-{
- AssetsIndex index;
- qDebug() << m_inst->name() << ": Finished asset index download";
-
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto profile = inst->getMinecraftProfile();
- auto assets = profile->getMinecraftAssets();
-
- QString asset_fname = "assets/indexes/" + assets->id + ".json";
- // FIXME: this looks like a job for a generic validator based on json schema?
- if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, &index))
- {
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json");
- metacache->evictEntry(entry);
- emitFailed(tr("Failed to read the assets index!"));
- }
-
- auto job = index.getDownloadJob();
- if(job)
- {
- setStatus(tr("Getting the assets files from Mojang..."));
- jarlibDownloadJob = job;
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished()));
- connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetsFailed);
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- jarlibDownloadJob->start();
- return;
- }
- assetsFinished();
-}
-
-void OneSixUpdate::assetIndexFailed(QString reason)
-{
- qDebug() << m_inst->name() << ": Failed asset index download";
- emitFailed(tr("Failed to download the assets index:\n%1").arg(reason));
-}
-
-void OneSixUpdate::assetsFinished()
-{
- emitSucceeded();
-}
-
-void OneSixUpdate::assetsFailed(QString reason)
-{
- emitFailed(tr("Failed to download assets:\n%1").arg(reason));
-}
-
-void OneSixUpdate::jarlibStart()
-{
- setStatus(tr("Getting the library files from Mojang..."));
- qDebug() << m_inst->name() << ": downloading libraries";
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- inst->reloadProfile();
- if(inst->flags() & BaseInstance::VersionBrokenFlag)
- {
- emitFailed(tr("Failed to load the version description files - check the instance for errors."));
- return;
- }
-
- // Build a list of URLs that will need to be downloaded.
- std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
- // minecraft.jar for this version
- {
- QString version_id = profile->getMinecraftVersion();
- QString localPath = version_id + "/" + version_id + ".jar";
- QString urlstr = profile->getMainJarUrl();
-
- auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
-
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("versions", localPath);
- job->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
- jarlibDownloadJob.reset(job);
- }
-
- auto libs = profile->getLibraries();
-
- auto metacache = ENV.metacache();
- QList<LibraryPtr> brokenLocalLibs;
-
- QStringList failedFiles;
- for (auto lib : libs)
- {
- auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles);
- for(auto dl : dls)
- {
- jarlibDownloadJob->addNetAction(dl);
- }
- }
- if (!brokenLocalLibs.empty())
- {
- jarlibDownloadJob.reset();
-
- QString failed_all = failedFiles.join("\n");
- emitFailed(tr("Some libraries marked as 'local' are missing their jar "
- "files:\n%1\n\nYou'll have to correct this problem manually. If this is "
- "an externally tracked instance, make sure to run it at least once "
- "outside of MultiMC.").arg(failed_all));
- return;
- }
-
- connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished()));
- connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::jarlibFailed);
- connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)),
- SIGNAL(progress(qint64, qint64)));
-
- jarlibDownloadJob->start();
-}
-
-void OneSixUpdate::jarlibFinished()
-{
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
-
- if (profile->hasTrait("legacyFML"))
- {
- fmllibsStart();
- }
- else
- {
- assetIndexStart();
- }
-}
-
-void OneSixUpdate::jarlibFailed(QString reason)
-{
- QStringList failed = jarlibDownloadJob->getFailedFiles();
- QString failed_all = failed.join("\n");
- emitFailed(
- tr("Failed to download the following files:\n%1\n\nReason:%2\nPlease try again.").arg(failed_all, reason));
-}
-
-void OneSixUpdate::fmllibsStart()
-{
- // Get the mod list
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- std::shared_ptr<MinecraftProfile> profile = inst->getMinecraftProfile();
- bool forge_present = false;
-
- QString version = inst->intendedVersionId();
- auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
- if (!fmlLibsMapping.contains(version))
- {
- assetIndexStart();
- return;
- }
-
- auto &libList = fmlLibsMapping[version];
-
- // determine if we need some libs for FML or forge
- setStatus(tr("Checking for FML libraries..."));
- forge_present = (profile->versionPatch("net.minecraftforge") != nullptr);
- // we don't...
- if (!forge_present)
- {
- assetIndexStart();
- return;
- }
-
- // now check the lib folder inside the instance for files.
- for (auto &lib : libList)
- {
- QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
- if (libInfo.exists())
- continue;
- fmlLibsToProcess.append(lib);
- }
-
- // if everything is in place, there's nothing to do here...
- if (fmlLibsToProcess.isEmpty())
- {
- assetIndexStart();
- return;
- }
-
- // download missing libs to our place
- setStatus(tr("Dowloading FML libraries..."));
- auto dljob = new NetJob("FML libraries");
- auto metacache = ENV.metacache();
- for (auto &lib : fmlLibsToProcess)
- {
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
- : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
- dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
- }
-
- connect(dljob, SIGNAL(succeeded()), SLOT(fmllibsFinished()));
- connect(dljob, &NetJob::failed, this, &OneSixUpdate::fmllibsFailed);
- connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
- legacyDownloadJob.reset(dljob);
- legacyDownloadJob->start();
-}
-
-void OneSixUpdate::fmllibsFinished()
-{
- legacyDownloadJob.reset();
- if (!fmlLibsToProcess.isEmpty())
- {
- setStatus(tr("Copying FML libraries into the instance..."));
- OneSixInstance *inst = (OneSixInstance *)m_inst;
- auto metacache = ENV.metacache();
- int index = 0;
- for (auto &lib : fmlLibsToProcess)
- {
- progress(index, fmlLibsToProcess.size());
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = FS::PathCombine(inst->libDir(), lib.filename);
- if (!FS::ensureFilePathExists(path))
- {
- emitFailed(tr("Failed creating FML library folder inside the instance."));
- return;
- }
- if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
- {
- emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
- return;
- }
- index++;
- }
- progress(index, fmlLibsToProcess.size());
- }
- assetIndexStart();
-}
-
-void OneSixUpdate::fmllibsFailed(QString reason)
-{
- emitFailed(tr("Game update failed: it was impossible to fetch the required FML libraries.\nReason:\n%1").arg(reason));
- return;
-}
-
diff --git a/libraries/logic/minecraft/onesix/OneSixUpdate.h b/libraries/logic/minecraft/onesix/OneSixUpdate.h
deleted file mode 100644
index b5195364..00000000
--- a/libraries/logic/minecraft/onesix/OneSixUpdate.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QList>
-#include <QUrl>
-
-#include "net/NetJob.h"
-#include "tasks/Task.h"
-#include "minecraft/VersionFilterData.h"
-#include <quazip.h>
-
-class MinecraftVersion;
-class OneSixInstance;
-
-class OneSixUpdate : public Task
-{
- Q_OBJECT
-public:
- explicit OneSixUpdate(OneSixInstance *inst, QObject *parent = 0);
- virtual void executeTask();
-
-private
-slots:
- void versionUpdateFailed(QString reason);
-
- void jarlibStart();
- void jarlibFinished();
- void jarlibFailed(QString reason);
-
- void fmllibsStart();
- void fmllibsFinished();
- void fmllibsFailed(QString reason);
-
- void assetIndexStart();
- void assetIndexFinished();
- void assetIndexFailed(QString reason);
-
- void assetsFinished();
- void assetsFailed(QString reason);
-
-private:
- NetJobPtr jarlibDownloadJob;
- NetJobPtr legacyDownloadJob;
-
- /// target version, determined during this task
- std::shared_ptr<MinecraftVersion> targetVersion;
- /// the task that is spawned for version updates
- std::shared_ptr<Task> versionUpdateTask;
-
- OneSixInstance *m_inst = nullptr;
- QList<FMLlib> fmlLibsToProcess;
-};
diff --git a/libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp b/libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp
deleted file mode 100644
index 541fb109..00000000
--- a/libraries/logic/minecraft/onesix/OneSixVersionFormat.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "OneSixVersionFormat.h"
-#include <Json.h>
-#include "minecraft/ParseUtils.h"
-#include <minecraft/MinecraftVersion.h>
-#include <minecraft/VersionBuildError.h>
-#include <minecraft/MojangVersionFormat.h>
-
-using namespace Json;
-
-static void readString(const QJsonObject &root, const QString &key, QString &variable)
-{
- if (root.contains(key))
- {
- variable = requireString(root.value(key));
- }
-}
-
-LibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename)
-{
- LibraryPtr out = MojangVersionFormat::libraryFromJson(libObj, filename);
- readString(libObj, "MMC-hint", out->m_hint);
- readString(libObj, "MMC-absulute_url", out->m_absoluteURL);
- readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL);
- return out;
-}
-
-QJsonObject OneSixVersionFormat::libraryToJson(Library *library)
-{
- QJsonObject libRoot = MojangVersionFormat::libraryToJson(library);
- if (library->m_absoluteURL.size())
- libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL);
- if (library->m_hint.size())
- libRoot.insert("MMC-hint", library->m_hint);
- return libRoot;
-}
-
-VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder)
-{
- VersionFilePtr out(new VersionFile());
- if (doc.isEmpty() || doc.isNull())
- {
- throw JSONValidationError(filename + " is empty or null");
- }
- if (!doc.isObject())
- {
- throw JSONValidationError(filename + " is not an object");
- }
-
- QJsonObject root = doc.object();
-
- if (requireOrder)
- {
- if (root.contains("order"))
- {
- out->order = requireInteger(root.value("order"));
- }
- else
- {
- // FIXME: evaluate if we don't want to throw exceptions here instead
- qCritical() << filename << "doesn't contain an order field";
- }
- }
-
- out->name = root.value("name").toString();
- out->fileId = root.value("fileId").toString();
- out->version = root.value("version").toString();
- out->dependsOnMinecraftVersion = root.value("mcVersion").toString();
- out->filename = filename;
-
- MojangVersionFormat::readVersionProperties(root, out.get());
-
- // added for legacy Minecraft window embedding, TODO: remove
- readString(root, "appletClass", out->appletClass);
-
- if (root.contains("+tweakers"))
- {
- for (auto tweakerVal : requireArray(root.value("+tweakers")))
- {
- out->addTweakers.append(requireString(tweakerVal));
- }
- }
-
- if (root.contains("+traits"))
- {
- for (auto tweakerVal : requireArray(root.value("+traits")))
- {
- out->traits.insert(requireString(tweakerVal));
- }
- }
-
- if (root.contains("+jarMods"))
- {
- for (auto libVal : requireArray(root.value("+jarMods")))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the jarmod
- auto lib = OneSixVersionFormat::jarModFromJson(libObj, filename, out->name);
- if(lib->originalName.isEmpty())
- {
- auto fixed = out->name;
- fixed.remove(" (jar mod)");
- lib->originalName = out->name;
- }
- // and add to jar mods
- out->jarMods.append(lib);
- }
- }
-
- auto readLibs = [&](const char * which)
- {
- for (auto libVal : requireArray(root.value(which)))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the library
- auto lib = libraryFromJson(libObj, filename);
- out->libraries.append(lib);
- }
- };
- bool hasPlusLibs = root.contains("+libraries");
- bool hasLibs = root.contains("libraries");
- if (hasPlusLibs && hasLibs)
- {
- out->addProblem(PROBLEM_WARNING, QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported."));
- readLibs("libraries");
- readLibs("+libraries");
- }
- else if (hasLibs)
- {
- readLibs("libraries");
- }
- else if(hasPlusLibs)
- {
- readLibs("+libraries");
- }
-
- /* removed features that shouldn't be used */
- if (root.contains("tweakers"))
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element 'tweakers'"));
- }
- if (root.contains("-libraries"))
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-libraries'"));
- }
- if (root.contains("-tweakers"))
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-tweakers'"));
- }
- if (root.contains("-minecraftArguments"))
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-minecraftArguments'"));
- }
- if (root.contains("+minecraftArguments"))
- {
- out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '+minecraftArguments'"));
- }
- return out;
-}
-
-QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch, bool saveOrder)
-{
- QJsonObject root;
- if (saveOrder)
- {
- root.insert("order", patch->order);
- }
- writeString(root, "name", patch->name);
- writeString(root, "fileId", patch->fileId);
- writeString(root, "version", patch->version);
- writeString(root, "mcVersion", patch->dependsOnMinecraftVersion);
-
- MojangVersionFormat::writeVersionProperties(patch.get(), root);
-
- writeString(root, "appletClass", patch->appletClass);
- writeStringList(root, "+tweakers", patch->addTweakers);
- writeStringList(root, "+traits", patch->traits.toList());
- if (!patch->libraries.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->libraries)
- {
- array.append(OneSixVersionFormat::libraryToJson(value.get()));
- }
- root.insert("+libraries", array);
- }
- if (!patch->jarMods.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->jarMods)
- {
- array.append(OneSixVersionFormat::jarModtoJson(value.get()));
- }
- root.insert("+jarMods", array);
- }
- // write the contents to a json document.
- {
- QJsonDocument out;
- out.setObject(root);
- return out;
- }
-}
-
-JarmodPtr OneSixVersionFormat::jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName)
-{
- JarmodPtr out(new Jarmod());
- if (!libObj.contains("name"))
- {
- throw JSONValidationError(filename +
- "contains a jarmod that doesn't have a 'name' field");
- }
- out->name = libObj.value("name").toString();
- out->originalName = libObj.value("originalName").toString();
- return out;
-}
-
-QJsonObject OneSixVersionFormat::jarModtoJson(Jarmod *jarmod)
-{
- QJsonObject out;
- writeString(out, "name", jarmod->name);
- if(!jarmod->originalName.isEmpty())
- {
- writeString(out, "originalName", jarmod->originalName);
- }
- return out;
-}
diff --git a/libraries/logic/minecraft/onesix/OneSixVersionFormat.h b/libraries/logic/minecraft/onesix/OneSixVersionFormat.h
deleted file mode 100644
index 5696e79e..00000000
--- a/libraries/logic/minecraft/onesix/OneSixVersionFormat.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <minecraft/VersionFile.h>
-#include <minecraft/MinecraftProfile.h>
-#include <minecraft/Library.h>
-#include <QJsonDocument>
-
-class OneSixVersionFormat
-{
-public:
- // version files / profile patches
- static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder);
- static QJsonDocument versionFileToJson(const VersionFilePtr &patch, bool saveOrder);
-
- // libraries
- static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject libraryToJson(Library *library);
-
- // jar mods
- static JarmodPtr jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName);
- static QJsonObject jarModtoJson(Jarmod * jarmod);
-};
diff --git a/libraries/logic/net/ByteArrayDownload.cpp b/libraries/logic/net/ByteArrayDownload.cpp
deleted file mode 100644
index 21990eeb..00000000
--- a/libraries/logic/net/ByteArrayDownload.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright 2013-2015 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 "ByteArrayDownload.h"
-#include "Env.h"
-#include <QDebug>
-
-ByteArrayDownload::ByteArrayDownload(QUrl url) : NetAction()
-{
- m_url = url;
- m_status = Job_NotStarted;
-}
-
-void ByteArrayDownload::start()
-{
- qDebug() << "Downloading " << m_url.toString();
- QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->get(request);
-
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
- SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
-}
-
-void ByteArrayDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
-
-void ByteArrayDownload::downloadError(QNetworkReply::NetworkError error)
-{
- // error happened during download.
- qCritical() << "Error getting URL:" << m_url.toString().toLocal8Bit()
- << "Network error: " << error;
- m_status = Job_Failed;
- m_errorString = m_reply->errorString();
-}
-
-void ByteArrayDownload::downloadFinished()
-{
- 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());
- qDebug() << "Following redirect to " << m_url.toString();
- start();
- return;
- }
-
- // if the download succeeded
- if (m_status != Job_Failed)
- {
- // nothing went wrong...
- m_status = Job_Finished;
- m_data = m_reply->readAll();
- m_content_type = m_reply->header(QNetworkRequest::ContentTypeHeader).toString();
- m_reply.reset();
- emit succeeded(m_index_within_job);
- return;
- }
- // else the download failed
- else
- {
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
-}
-
-void ByteArrayDownload::downloadReadyRead()
-{
- // ~_~
-}
diff --git a/libraries/logic/net/ByteArrayDownload.h b/libraries/logic/net/ByteArrayDownload.h
deleted file mode 100644
index e2fc2911..00000000
--- a/libraries/logic/net/ByteArrayDownload.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include "NetAction.h"
-
-#include "multimc_logic_export.h"
-
-typedef std::shared_ptr<class ByteArrayDownload> ByteArrayDownloadPtr;
-class MULTIMC_LOGIC_EXPORT ByteArrayDownload : public NetAction
-{
- Q_OBJECT
-public:
- ByteArrayDownload(QUrl url);
- static ByteArrayDownloadPtr make(QUrl url)
- {
- return ByteArrayDownloadPtr(new ByteArrayDownload(url));
- }
- virtual ~ByteArrayDownload() {};
-public:
- /// if not saving to file, downloaded data is placed here
- QByteArray m_data;
-
- QString m_errorString;
-
-public
-slots:
- virtual void start();
-
-protected
-slots:
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- void downloadError(QNetworkReply::NetworkError error);
- void downloadFinished();
- void downloadReadyRead();
-};
diff --git a/libraries/logic/net/CacheDownload.cpp b/libraries/logic/net/CacheDownload.cpp
deleted file mode 100644
index 1ac55180..00000000
--- a/libraries/logic/net/CacheDownload.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright 2013-2015 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 "CacheDownload.h"
-
-#include <QCryptographicHash>
-#include <QFileInfo>
-#include <QDateTime>
-#include <QDebug>
-#include "Env.h"
-#include <FileSystem.h>
-
-CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry)
- : NetAction(), md5sum(QCryptographicHash::Md5)
-{
- m_url = url;
- m_entry = entry;
- m_target_path = entry->getFullPath();
- m_status = Job_NotStarted;
-}
-
-void CacheDownload::start()
-{
- m_status = Job_InProgress;
- if (!m_entry->isStale())
- {
- m_status = Job_Finished;
- emit succeeded(m_index_within_job);
- return;
- }
- // create a new save file
- m_output_file.reset(new QSaveFile(m_target_path));
-
- // if there already is a file and md5 checking is in effect and it can be opened
- if (!FS::ensureFilePathExists(m_target_path))
- {
- qCritical() << "Could not create folder for " + m_target_path;
- m_status = Job_Failed;
- emit failed(m_index_within_job);
- return;
- }
- if (!m_output_file->open(QIODevice::WriteOnly))
- {
- qCritical() << "Could not open " + m_target_path + " for writing";
- m_status = Job_Failed;
- emit failed(m_index_within_job);
- return;
- }
- qDebug() << "Downloading " << m_url.toString();
- QNetworkRequest request(m_url);
-
- // check file consistency first.
- QFile current(m_target_path);
- if(current.exists() && current.size() != 0)
- {
- if (m_entry->getRemoteChangedTimestamp().size())
- request.setRawHeader(QString("If-Modified-Since").toLatin1(),
- m_entry->getRemoteChangedTimestamp().toLatin1());
- if (m_entry->getETag().size())
- request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
- }
-
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->get(request);
-
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
- SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
-}
-
-void CacheDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
-
-void CacheDownload::downloadError(QNetworkReply::NetworkError error)
-{
- // error happened during download.
- qCritical() << "Failed " << m_url.toString() << " with reason " << error;
- m_status = Job_Failed;
-}
-void CacheDownload::downloadFinished()
-{
- 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());
- qDebug() << "Following redirect to " << m_url.toString();
- start();
- return;
- }
-
- // if the download succeeded
- if (m_status == Job_Failed)
- {
- m_output_file->cancelWriting();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
-
- // if we wrote any data to the save file, we try to commit the data to the real file.
- if (wroteAnyData)
- {
- // nothing went wrong...
- if (m_output_file->commit())
- {
- m_status = Job_Finished;
- m_entry->setMD5Sum(md5sum.result().toHex().constData());
- }
- else
- {
- qCritical() << "Failed to commit changes to " << m_target_path;
- m_output_file->cancelWriting();
- m_reply.reset();
- m_status = Job_Failed;
- emit failed(m_index_within_job);
- return;
- }
- }
- else
- {
- m_status = Job_Finished;
- }
-
- // then get rid of the save file
- m_output_file.reset();
-
- QFileInfo output_file_info(m_target_path);
-
- m_entry->setETag(m_reply->rawHeader("ETag").constData());
- if (m_reply->hasRawHeader("Last-Modified"))
- {
- m_entry->setRemoteChangedTimestamp(m_reply->rawHeader("Last-Modified").constData());
- }
- m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
- m_entry->setStale(false);
- ENV.metacache()->updateEntry(m_entry);
-
- m_reply.reset();
- emit succeeded(m_index_within_job);
- return;
-}
-
-void CacheDownload::downloadReadyRead()
-{
- QByteArray ba = m_reply->readAll();
- md5sum.addData(ba);
- if (m_output_file->write(ba) != ba.size())
- {
- qCritical() << "Failed writing into " + m_target_path;
- m_status = Job_Failed;
- m_output_file->cancelWriting();
- m_output_file.reset();
- emit failed(m_index_within_job);
- wroteAnyData = false;
- return;
- }
- wroteAnyData = true;
-}
diff --git a/libraries/logic/net/CacheDownload.h b/libraries/logic/net/CacheDownload.h
deleted file mode 100644
index d83b2a0f..00000000
--- a/libraries/logic/net/CacheDownload.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "NetAction.h"
-#include "HttpMetaCache.h"
-#include <QCryptographicHash>
-#include <QSaveFile>
-
-#include "multimc_logic_export.h"
-
-typedef std::shared_ptr<class CacheDownload> CacheDownloadPtr;
-class MULTIMC_LOGIC_EXPORT CacheDownload : public NetAction
-{
- Q_OBJECT
-private:
- MetaEntryPtr m_entry;
- /// if saving to file, use the one specified in this string
- QString m_target_path;
-
- /// this is the output file, if any
- std::unique_ptr<QSaveFile> m_output_file;
-
- /// the hash-as-you-download
- QCryptographicHash md5sum;
-
- bool wroteAnyData = false;
-
-public:
- explicit CacheDownload(QUrl url, MetaEntryPtr entry);
- static CacheDownloadPtr make(QUrl url, MetaEntryPtr entry)
- {
- return CacheDownloadPtr(new CacheDownload(url, entry));
- }
- virtual ~CacheDownload(){};
- QString getTargetFilepath()
- {
- return m_target_path;
- }
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead();
-
-public
-slots:
- virtual void start();
-};
diff --git a/libraries/logic/net/HttpMetaCache.cpp b/libraries/logic/net/HttpMetaCache.cpp
deleted file mode 100644
index ea3e2834..00000000
--- a/libraries/logic/net/HttpMetaCache.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Copyright 2013-2015 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 "Env.h"
-#include "HttpMetaCache.h"
-#include "FileSystem.h"
-
-#include <QFileInfo>
-#include <QFile>
-#include <QDateTime>
-#include <QCryptographicHash>
-
-#include <QDebug>
-
-#include <QJsonDocument>
-#include <QJsonArray>
-#include <QJsonObject>
-
-QString MetaEntry::getFullPath()
-{
- // FIXME: make local?
- return FS::PathCombine(basePath, relativePath);
-}
-
-HttpMetaCache::HttpMetaCache(QString path) : QObject()
-{
- m_index_file = path;
- saveBatchingTimer.setSingleShot(true);
- saveBatchingTimer.setTimerType(Qt::VeryCoarseTimer);
- connect(&saveBatchingTimer, SIGNAL(timeout()), SLOT(SaveNow()));
-}
-
-HttpMetaCache::~HttpMetaCache()
-{
- saveBatchingTimer.stop();
- SaveNow();
-}
-
-MetaEntryPtr HttpMetaCache::getEntry(QString base, QString resource_path)
-{
- // no base. no base path. can't store
- if (!m_entries.contains(base))
- {
- // TODO: log problem
- return MetaEntryPtr();
- }
- EntryMap &map = m_entries[base];
- if (map.entry_list.contains(resource_path))
- {
- return map.entry_list[resource_path];
- }
- return MetaEntryPtr();
-}
-
-MetaEntryPtr HttpMetaCache::resolveEntry(QString base, QString resource_path, QString expected_etag)
-{
- auto entry = getEntry(base, resource_path);
- // it's not present? generate a default stale entry
- if (!entry)
- {
- return staleEntry(base, resource_path);
- }
-
- auto &selected_base = m_entries[base];
- QString real_path = FS::PathCombine(selected_base.base_path, resource_path);
- QFileInfo finfo(real_path);
-
- // is the file really there? if not -> stale
- if (!finfo.isFile() || !finfo.isReadable())
- {
- // if the file doesn't exist, we disown the entry
- selected_base.entry_list.remove(resource_path);
- return staleEntry(base, resource_path);
- }
-
- if (!expected_etag.isEmpty() && expected_etag != entry->etag)
- {
- // if the etag doesn't match expected, we disown the entry
- selected_base.entry_list.remove(resource_path);
- return staleEntry(base, resource_path);
- }
-
- // if the file changed, check md5sum
- qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
- if (file_last_changed != entry->local_changed_timestamp)
- {
- QFile input(real_path);
- input.open(QIODevice::ReadOnly);
- QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5)
- .toHex()
- .constData();
- if (entry->md5sum != md5sum)
- {
- selected_base.entry_list.remove(resource_path);
- return staleEntry(base, resource_path);
- }
- // md5sums matched... keep entry and save the new state to file
- entry->local_changed_timestamp = file_last_changed;
- SaveEventually();
- }
-
- // entry passed all the checks we cared about.
- entry->basePath = getBasePath(base);
- return entry;
-}
-
-bool HttpMetaCache::updateEntry(MetaEntryPtr stale_entry)
-{
- if (!m_entries.contains(stale_entry->baseId))
- {
- qCritical() << "Cannot add entry with unknown base: "
- << stale_entry->baseId.toLocal8Bit();
- return false;
- }
- if (stale_entry->stale)
- {
- qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
- return false;
- }
- m_entries[stale_entry->baseId].entry_list[stale_entry->relativePath] = stale_entry;
- SaveEventually();
- return true;
-}
-
-bool HttpMetaCache::evictEntry(MetaEntryPtr entry)
-{
- if(entry)
- {
- entry->stale = true;
- SaveEventually();
- return true;
- }
- return false;
-}
-
-MetaEntryPtr HttpMetaCache::staleEntry(QString base, QString resource_path)
-{
- auto foo = new MetaEntry();
- foo->baseId = base;
- foo->basePath = getBasePath(base);
- foo->relativePath = resource_path;
- foo->stale = true;
- return MetaEntryPtr(foo);
-}
-
-void HttpMetaCache::addBase(QString base, QString base_root)
-{
- // TODO: report error
- if (m_entries.contains(base))
- return;
- // TODO: check if the base path is valid
- EntryMap foo;
- foo.base_path = base_root;
- m_entries[base] = foo;
-}
-
-QString HttpMetaCache::getBasePath(QString base)
-{
- if (m_entries.contains(base))
- {
- return m_entries[base].base_path;
- }
- return QString();
-}
-
-void HttpMetaCache::Load()
-{
- if(m_index_file.isNull())
- return;
-
- QFile index(m_index_file);
- if (!index.open(QIODevice::ReadOnly))
- return;
-
- QJsonDocument json = QJsonDocument::fromJson(index.readAll());
- if (!json.isObject())
- return;
- auto root = json.object();
- // check file version first
- auto version_val = root.value("version");
- if (!version_val.isString())
- return;
- if (version_val.toString() != "1")
- return;
-
- // read the entry array
- auto entries_val = root.value("entries");
- if (!entries_val.isArray())
- return;
- QJsonArray array = entries_val.toArray();
- for (auto element : array)
- {
- if (!element.isObject())
- return;
- auto element_obj = element.toObject();
- QString base = element_obj.value("base").toString();
- if (!m_entries.contains(base))
- continue;
- auto &entrymap = m_entries[base];
- auto foo = new MetaEntry();
- foo->baseId = base;
- QString path = foo->relativePath = element_obj.value("path").toString();
- foo->md5sum = element_obj.value("md5sum").toString();
- foo->etag = element_obj.value("etag").toString();
- foo->local_changed_timestamp = element_obj.value("last_changed_timestamp").toDouble();
- foo->remote_changed_timestamp =
- element_obj.value("remote_changed_timestamp").toString();
- // presumed innocent until closer examination
- foo->stale = false;
- entrymap.entry_list[path] = MetaEntryPtr(foo);
- }
-}
-
-void HttpMetaCache::SaveEventually()
-{
- // reset the save timer
- saveBatchingTimer.stop();
- saveBatchingTimer.start(30000);
-}
-
-void HttpMetaCache::SaveNow()
-{
- if(m_index_file.isNull())
- return;
- QJsonObject toplevel;
- toplevel.insert("version", QJsonValue(QString("1")));
- QJsonArray entriesArr;
- for (auto group : m_entries)
- {
- for (auto entry : group.entry_list)
- {
- // do not save stale entries. they are dead.
- if(entry->stale)
- {
- continue;
- }
- QJsonObject entryObj;
- entryObj.insert("base", QJsonValue(entry->baseId));
- entryObj.insert("path", QJsonValue(entry->relativePath));
- entryObj.insert("md5sum", QJsonValue(entry->md5sum));
- entryObj.insert("etag", QJsonValue(entry->etag));
- entryObj.insert("last_changed_timestamp",
- QJsonValue(double(entry->local_changed_timestamp)));
- if (!entry->remote_changed_timestamp.isEmpty())
- entryObj.insert("remote_changed_timestamp",
- QJsonValue(entry->remote_changed_timestamp));
- entriesArr.append(entryObj);
- }
- }
- toplevel.insert("entries", entriesArr);
-
- QJsonDocument doc(toplevel);
- try
- {
- FS::write(m_index_file, doc.toJson());
- }
- catch (Exception & e)
- {
- qWarning() << e.what();
- }
-}
diff --git a/libraries/logic/net/HttpMetaCache.h b/libraries/logic/net/HttpMetaCache.h
deleted file mode 100644
index 7b626c70..00000000
--- a/libraries/logic/net/HttpMetaCache.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <QString>
-#include <QMap>
-#include <qtimer.h>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class HttpMetaCache;
-
-class MULTIMC_LOGIC_EXPORT MetaEntry
-{
-friend class HttpMetaCache;
-protected:
- MetaEntry() {}
-public:
- bool isStale()
- {
- return stale;
- }
- void setStale(bool stale)
- {
- this->stale = stale;
- }
- QString getFullPath();
- QString getRemoteChangedTimestamp()
- {
- return remote_changed_timestamp;
- }
- void setRemoteChangedTimestamp(QString remote_changed_timestamp)
- {
- this->remote_changed_timestamp = remote_changed_timestamp;
- }
- void setLocalChangedTimestamp(qint64 timestamp)
- {
- local_changed_timestamp = timestamp;
- }
- QString getETag()
- {
- return etag;
- }
- void setETag(QString etag)
- {
- this->etag = etag;
- }
- QString getMD5Sum()
- {
- return md5sum;
- }
- void setMD5Sum(QString md5sum)
- {
- this->md5sum = md5sum;
- }
-protected:
- QString baseId;
- QString basePath;
- QString relativePath;
- QString md5sum;
- QString etag;
- qint64 local_changed_timestamp = 0;
- QString remote_changed_timestamp; // QString for now, RFC 2822 encoded time
- bool stale = true;
-};
-
-typedef std::shared_ptr<MetaEntry> MetaEntryPtr;
-
-class MULTIMC_LOGIC_EXPORT HttpMetaCache : public QObject
-{
- Q_OBJECT
-public:
- // supply path to the cache index file
- HttpMetaCache(QString path = QString());
- ~HttpMetaCache();
-
- // get the entry solely from the cache
- // you probably don't want this, unless you have some specific caching needs.
- MetaEntryPtr getEntry(QString base, QString resource_path);
-
- // get the entry from cache and verify that it isn't stale (within reason)
- MetaEntryPtr resolveEntry(QString base, QString resource_path,
- QString expected_etag = QString());
-
- // add a previously resolved stale entry
- bool updateEntry(MetaEntryPtr stale_entry);
-
- // evict selected entry from cache
- bool evictEntry(MetaEntryPtr entry);
-
- void addBase(QString base, QString base_root);
-
- // (re)start a timer that calls SaveNow later.
- void SaveEventually();
- void Load();
- QString getBasePath(QString base);
-public
-slots:
- void SaveNow();
-
-private:
- // create a new stale entry, given the parameters
- MetaEntryPtr staleEntry(QString base, QString resource_path);
- struct EntryMap
- {
- QString base_path;
- QMap<QString, MetaEntryPtr> entry_list;
- };
- QMap<QString, EntryMap> m_entries;
- QString m_index_file;
- QTimer saveBatchingTimer;
-};
diff --git a/libraries/logic/net/MD5EtagDownload.cpp b/libraries/logic/net/MD5EtagDownload.cpp
deleted file mode 100644
index 3b4d5dcd..00000000
--- a/libraries/logic/net/MD5EtagDownload.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Copyright 2013-2015 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 "Env.h"
-#include "MD5EtagDownload.h"
-#include <FileSystem.h>
-#include <QCryptographicHash>
-#include <QDebug>
-
-MD5EtagDownload::MD5EtagDownload(QUrl url, QString target_path) : NetAction()
-{
- m_url = url;
- m_target_path = target_path;
- m_status = Job_NotStarted;
-}
-
-void MD5EtagDownload::start()
-{
- QString filename = m_target_path;
- m_output_file.setFileName(filename);
- // if there already is a file and md5 checking is in effect and it can be opened
- if (m_output_file.exists() && m_output_file.open(QIODevice::ReadOnly))
- {
- // get the md5 of the local file.
- m_local_md5 =
- QCryptographicHash::hash(m_output_file.readAll(), QCryptographicHash::Md5)
- .toHex()
- .constData();
- m_output_file.close();
- // if we are expecting some md5sum, compare it with the local one
- if (!m_expected_md5.isEmpty())
- {
- // skip if they match
- if(m_local_md5 == m_expected_md5)
- {
- qDebug() << "Skipping " << m_url.toString() << ": md5 match.";
- emit succeeded(m_index_within_job);
- return;
- }
- }
- else
- {
- // no expected md5. we use the local md5sum as an ETag
- }
- }
- if (!FS::ensureFilePathExists(filename))
- {
- emit failed(m_index_within_job);
- return;
- }
-
- QNetworkRequest request(m_url);
-
- qDebug() << "Downloading " << m_url.toString() << " local MD5: " << m_local_md5;
-
- if(!m_local_md5.isEmpty())
- {
- request.setRawHeader(QString("If-None-Match").toLatin1(), m_local_md5.toLatin1());
- }
- if(!m_expected_md5.isEmpty())
- qDebug() << "Expecting " << m_expected_md5;
-
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
-
- // Go ahead and try to open the file.
- // If we don't do this, empty files won't be created, which breaks the updater.
- // Plus, this way, we don't end up starting a download for a file we can't open.
- if (!m_output_file.open(QIODevice::WriteOnly))
- {
- emit failed(m_index_within_job);
- return;
- }
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->get(request);
-
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
- SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
-}
-
-void MD5EtagDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
-
-void MD5EtagDownload::downloadError(QNetworkReply::NetworkError error)
-{
- qCritical() << "Error" << error << ":" << m_reply->errorString() << "while downloading"
- << m_reply->url();
- m_status = Job_Failed;
-}
-
-void MD5EtagDownload::downloadFinished()
-{
- // if the download succeeded
- if (m_status != Job_Failed)
- {
- // nothing went wrong...
- m_status = Job_Finished;
- m_output_file.close();
-
- // FIXME: compare with the real written data md5sum
- // this is just an ETag
- qDebug() << "Finished " << m_url.toString() << " got " << m_reply->rawHeader("ETag").constData();
-
- m_reply.reset();
- emit succeeded(m_index_within_job);
- return;
- }
- // else the download failed
- else
- {
- m_output_file.close();
- m_output_file.remove();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
-}
-
-void MD5EtagDownload::downloadReadyRead()
-{
- if (!m_output_file.isOpen())
- {
- if (!m_output_file.open(QIODevice::WriteOnly))
- {
- /*
- * Can't open the file... the job failed
- */
- m_reply->abort();
- emit failed(m_index_within_job);
- return;
- }
- }
- m_output_file.write(m_reply->readAll());
-}
diff --git a/libraries/logic/net/MD5EtagDownload.h b/libraries/logic/net/MD5EtagDownload.h
deleted file mode 100644
index cd1cb550..00000000
--- a/libraries/logic/net/MD5EtagDownload.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "NetAction.h"
-#include <QFile>
-
-typedef std::shared_ptr<class MD5EtagDownload> Md5EtagDownloadPtr;
-class MD5EtagDownload : public NetAction
-{
- Q_OBJECT
-public:
- /// the expected md5 checksum. Only set from outside
- QString m_expected_md5;
- /// the md5 checksum of a file that already exists.
- QString m_local_md5;
- /// if saving to file, use the one specified in this string
- QString m_target_path;
- /// this is the output file, if any
- QFile m_output_file;
-
-public:
- explicit MD5EtagDownload(QUrl url, QString target_path);
- static Md5EtagDownloadPtr make(QUrl url, QString target_path)
- {
- return Md5EtagDownloadPtr(new MD5EtagDownload(url, target_path));
- }
- virtual ~MD5EtagDownload(){};
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead();
-
-public
-slots:
- virtual void start();
-};
diff --git a/libraries/logic/net/NetAction.h b/libraries/logic/net/NetAction.h
deleted file mode 100644
index 3c395605..00000000
--- a/libraries/logic/net/NetAction.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QUrl>
-#include <memory>
-#include <QNetworkReply>
-#include <QObjectPtr.h>
-
-#include "multimc_logic_export.h"
-
-enum JobStatus
-{
- Job_NotStarted,
- Job_InProgress,
- Job_Finished,
- Job_Failed
-};
-
-typedef std::shared_ptr<class NetAction> NetActionPtr;
-class MULTIMC_LOGIC_EXPORT NetAction : public QObject
-{
- Q_OBJECT
-protected:
- explicit NetAction() : QObject(0) {};
-
-public:
- virtual ~NetAction() {};
-
-public:
- virtual qint64 totalProgress() const
- {
- return m_total_progress;
- }
- virtual qint64 currentProgress() const
- {
- return m_progress;
- }
- virtual qint64 numberOfFailures() const
- {
- return m_failures;
- }
-
-public:
- /// the network reply
- unique_qobject_ptr<QNetworkReply> m_reply;
-
- /// the content of the content-type header
- QString m_content_type;
-
- /// source URL
- QUrl m_url;
-
- /// The file's status
- JobStatus m_status = Job_NotStarted;
-
- /// index within the parent job
- int m_index_within_job = 0;
-
- qint64 m_progress = 0;
- qint64 m_total_progress = 1;
-
- /// number of failures up to this point
- int m_failures = 0;
-
-signals:
- void started(int index);
- void netActionProgress(int index, qint64 current, qint64 total);
- void succeeded(int index);
- void failed(int index);
-
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) = 0;
- virtual void downloadError(QNetworkReply::NetworkError error) = 0;
- virtual void downloadFinished() = 0;
- virtual void downloadReadyRead() = 0;
-
-public
-slots:
- virtual void start() = 0;
-};
diff --git a/libraries/logic/net/NetJob.cpp b/libraries/logic/net/NetJob.cpp
deleted file mode 100644
index 76c61c35..00000000
--- a/libraries/logic/net/NetJob.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Copyright 2013-2015 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 "NetJob.h"
-#include "MD5EtagDownload.h"
-#include "ByteArrayDownload.h"
-#include "CacheDownload.h"
-
-#include <QDebug>
-
-void NetJob::partSucceeded(int index)
-{
- // do progress. all slots are 1 in size at least
- auto &slot = parts_progress[index];
- partProgress(index, slot.total_progress, slot.total_progress);
-
- m_doing.remove(index);
- m_done.insert(index);
- downloads[index].get()->disconnect(this);
- startMoreParts();
-}
-
-void NetJob::partFailed(int index)
-{
- m_doing.remove(index);
- auto &slot = parts_progress[index];
- if (slot.failures == 3)
- {
- m_failed.insert(index);
- }
- else
- {
- slot.failures++;
- m_todo.enqueue(index);
- }
- downloads[index].get()->disconnect(this);
- startMoreParts();
-}
-
-void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal)
-{
- auto &slot = parts_progress[index];
-
- current_progress -= slot.current_progress;
- slot.current_progress = bytesReceived;
- current_progress += slot.current_progress;
-
- total_progress -= slot.total_progress;
- slot.total_progress = bytesTotal;
- total_progress += slot.total_progress;
- setProgress(current_progress, total_progress);
-}
-
-void NetJob::executeTask()
-{
- qDebug() << m_job_name.toLocal8Bit() << " started.";
- m_running = true;
- for (int i = 0; i < downloads.size(); i++)
- {
- m_todo.enqueue(i);
- }
- // hack that delays early failures so they can be caught easier
- QMetaObject::invokeMethod(this, "startMoreParts", Qt::QueuedConnection);
-}
-
-void NetJob::startMoreParts()
-{
- // check for final conditions if there's nothing in the queue
- if(!m_todo.size())
- {
- if(!m_doing.size())
- {
- if(!m_failed.size())
- {
- qDebug() << m_job_name << "succeeded.";
- emitSucceeded();
- }
- else
- {
- qCritical() << m_job_name << "failed.";
- emitFailed(tr("Job '%1' failed to process:\n%2").arg(m_job_name).arg(getFailedFiles().join("\n")));
- }
- }
- return;
- }
- // otherwise try to start more parts
- while (m_doing.size() < 6)
- {
- if(!m_todo.size())
- return;
- int doThis = m_todo.dequeue();
- m_doing.insert(doThis);
- auto part = downloads[doThis];
- // connect signals :D
- connect(part.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
- connect(part.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
- connect(part.get(), SIGNAL(netActionProgress(int, qint64, qint64)),
- SLOT(partProgress(int, qint64, qint64)));
- part->start();
- }
-}
-
-
-QStringList NetJob::getFailedFiles()
-{
- QStringList failed;
- for (auto index: m_failed)
- {
- failed.push_back(downloads[index]->m_url.toString());
- }
- failed.sort();
- return failed;
-}
diff --git a/libraries/logic/net/NetJob.h b/libraries/logic/net/NetJob.h
deleted file mode 100644
index 167fe176..00000000
--- a/libraries/logic/net/NetJob.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <QtNetwork>
-#include "NetAction.h"
-#include "ByteArrayDownload.h"
-#include "MD5EtagDownload.h"
-#include "CacheDownload.h"
-#include "HttpMetaCache.h"
-#include "tasks/Task.h"
-#include "QObjectPtr.h"
-
-#include "multimc_logic_export.h"
-
-class NetJob;
-typedef shared_qobject_ptr<NetJob> NetJobPtr;
-
-class MULTIMC_LOGIC_EXPORT NetJob : public Task
-{
- Q_OBJECT
-public:
- explicit NetJob(QString job_name) : Task(), m_job_name(job_name) {}
- virtual ~NetJob() {}
- bool addNetAction(NetActionPtr action)
- {
- action->m_index_within_job = downloads.size();
- downloads.append(action);
- part_info pi;
- {
- pi.current_progress = action->currentProgress();
- pi.total_progress = action->totalProgress();
- pi.failures = action->numberOfFailures();
- }
- parts_progress.append(pi);
- total_progress += pi.total_progress;
- // if this is already running, the action needs to be started right away!
- if (isRunning())
- {
- setProgress(current_progress, total_progress);
- connect(action.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
- connect(action.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
- connect(action.get(), SIGNAL(netActionProgress(int, qint64, qint64)),
- SLOT(partProgress(int, qint64, qint64)));
- action->start();
- }
- return true;
- }
-
- NetActionPtr operator[](int index)
- {
- return downloads[index];
- }
- const NetActionPtr at(const int index)
- {
- return downloads.at(index);
- }
- NetActionPtr first()
- {
- if (downloads.size())
- return downloads[0];
- return NetActionPtr();
- }
- int size() const
- {
- return downloads.size();
- }
- virtual bool isRunning() const
- {
- return m_running;
- }
- QStringList getFailedFiles();
-
-private slots:
- void startMoreParts();
-
-public slots:
- virtual void executeTask();
- // FIXME: implement
- virtual bool abort() {return false;};
-
-private slots:
- void partProgress(int index, qint64 bytesReceived, qint64 bytesTotal);
- void partSucceeded(int index);
- void partFailed(int index);
-
-private:
- struct part_info
- {
- qint64 current_progress = 0;
- qint64 total_progress = 1;
- int failures = 0;
- bool connected = false;
- };
- QString m_job_name;
- QList<NetActionPtr> downloads;
- QList<part_info> parts_progress;
- QQueue<int> m_todo;
- QSet<int> m_doing;
- QSet<int> m_done;
- QSet<int> m_failed;
- qint64 current_progress = 0;
- qint64 total_progress = 0;
- bool m_running = false;
-};
diff --git a/libraries/logic/net/PasteUpload.cpp b/libraries/logic/net/PasteUpload.cpp
deleted file mode 100644
index 4b671d6f..00000000
--- a/libraries/logic/net/PasteUpload.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include "PasteUpload.h"
-#include "Env.h"
-#include <QDebug>
-#include <QJsonObject>
-#include <QJsonDocument>
-
-PasteUpload::PasteUpload(QWidget *window, QString text, QString key) : m_window(window)
-{
- m_key = key;
- QByteArray temp;
- temp = text.toUtf8();
- temp.replace('\n', "\r\n");
- m_textSize = temp.size();
- m_text = "key=" + m_key.toLatin1() + "&description=MultiMC5+Log+File&language=plain&format=json&expire=2592000&paste=" + temp.toPercentEncoding();
- buf = new QBuffer(&m_text);
-}
-
-PasteUpload::~PasteUpload()
-{
- if(buf)
- {
- delete buf;
- }
-}
-
-bool PasteUpload::validateText()
-{
- return m_textSize <= maxSize();
-}
-
-void PasteUpload::executeTask()
-{
- QNetworkRequest request(QUrl("http://paste.ee/api"));
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
-
- request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
- request.setRawHeader("Content-Length", QByteArray::number(m_text.size()));
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->post(request, buf);
-
- m_reply = std::shared_ptr<QNetworkReply>(rep);
- setStatus(tr("Uploading to paste.ee"));
- connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished()));
-}
-
-void PasteUpload::downloadError(QNetworkReply::NetworkError error)
-{
- // error happened during download.
- qCritical() << "Network error: " << error;
- emitFailed(m_reply->errorString());
-}
-
-void PasteUpload::downloadFinished()
-{
- // if the download succeeded
- if (m_reply->error() == QNetworkReply::NetworkError::NoError)
- {
- QByteArray data = m_reply->readAll();
- m_reply.reset();
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed(jsonError.errorString());
- return;
- }
- if (!parseResult(doc))
- {
- emitFailed(tr("paste.ee returned an error. Please consult the logs for more information"));
- return;
- }
- }
- // else the download failed
- else
- {
- emitFailed(QString("Network error: %1").arg(m_reply->errorString()));
- m_reply.reset();
- return;
- }
- emitSucceeded();
-}
-
-bool PasteUpload::parseResult(QJsonDocument doc)
-{
- auto object = doc.object();
- auto status = object.value("status").toString("error");
- if (status == "error")
- {
- qCritical() << "paste.ee reported error:" << QString(object.value("error").toString());
- return false;
- }
- m_pasteLink = object.value("paste").toObject().value("link").toString();
- m_pasteID = object.value("paste").toObject().value("id").toString();
- return true;
-}
-
diff --git a/libraries/logic/net/PasteUpload.h b/libraries/logic/net/PasteUpload.h
deleted file mode 100644
index 06e3f955..00000000
--- a/libraries/logic/net/PasteUpload.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-#include "tasks/Task.h"
-#include <QNetworkReply>
-#include <QBuffer>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT PasteUpload : public Task
-{
- Q_OBJECT
-public:
- PasteUpload(QWidget *window, QString text, QString key = "public");
- virtual ~PasteUpload();
- QString pasteLink()
- {
- return m_pasteLink;
- }
- QString pasteID()
- {
- return m_pasteID;
- }
- uint32_t maxSize()
- {
- // 2MB for paste.ee - public
- if(m_key == "public")
- return 1024*1024*2;
- // 12MB for paste.ee - with actual key
- return 1024*1024*12;
- }
- bool validateText();
-protected:
- virtual void executeTask();
-
-private:
- bool parseResult(QJsonDocument doc);
- QByteArray m_text;
- QString m_error;
- QWidget *m_window;
- QString m_pasteID;
- QString m_pasteLink;
- QString m_key;
- int m_textSize = 0;
- QBuffer * buf = nullptr;
- std::shared_ptr<QNetworkReply> m_reply;
-public
-slots:
- void downloadError(QNetworkReply::NetworkError);
- void downloadFinished();
-};
diff --git a/libraries/logic/net/URLConstants.cpp b/libraries/logic/net/URLConstants.cpp
deleted file mode 100644
index bd476b2c..00000000
--- a/libraries/logic/net/URLConstants.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "URLConstants.h"
-
-namespace URLConstants {
-
-QString getLegacyJarUrl(QString version)
-{
- return "http://" + AWS_DOWNLOAD_VERSIONS + getJarPath(version);
-}
-
-QString getJarPath(QString version)
-{
- return version + "/" + version + ".jar";
-}
-
-
-}
diff --git a/libraries/logic/net/URLConstants.h b/libraries/logic/net/URLConstants.h
deleted file mode 100644
index 8923ef54..00000000
--- a/libraries/logic/net/URLConstants.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-
-namespace URLConstants
-{
-const QString AWS_DOWNLOAD_VERSIONS("s3.amazonaws.com/Minecraft.Download/versions/");
-const QString RESOURCE_BASE("resources.download.minecraft.net/");
-const QString LIBRARY_BASE("libraries.minecraft.net/");
-//const QString SKINS_BASE("skins.minecraft.net/MinecraftSkins/");
-const QString SKINS_BASE("crafatar.com/skins/");
-const QString AUTH_BASE("authserver.mojang.com/");
-const QString FORGE_LEGACY_URL("http://files.minecraftforge.net/minecraftforge/json");
-const QString FORGE_GRADLE_URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/json");
-const QString MOJANG_STATUS_URL("http://status.mojang.com/check");
-const QString MOJANG_STATUS_NEWS_URL("http://status.mojang.com/news");
-const QString LITELOADER_URL("http://dl.liteloader.com/versions/versions.json");
-const QString IMGUR_BASE_URL("https://api.imgur.com/3/");
-const QString FMLLIBS_OUR_BASE_URL("http://files.multimc.org/fmllibs/");
-const QString FMLLIBS_FORGE_BASE_URL("http://files.minecraftforge.net/fmllibs/");
-const QString TRANSLATIONS_BASE_URL("http://files.multimc.org/translations/");
-
-QString getJarPath(QString version);
-QString getLegacyJarUrl(QString version);
-}
diff --git a/libraries/logic/news/NewsChecker.cpp b/libraries/logic/news/NewsChecker.cpp
deleted file mode 100644
index be4aa1d1..00000000
--- a/libraries/logic/news/NewsChecker.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright 2013-2015 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 "NewsChecker.h"
-
-#include <QByteArray>
-#include <QDomDocument>
-
-#include <QDebug>
-
-NewsChecker::NewsChecker(const QString& feedUrl)
-{
- m_feedUrl = feedUrl;
-}
-
-void NewsChecker::reloadNews()
-{
- // Start a netjob to download the RSS feed and call rssDownloadFinished() when it's done.
- if (isLoadingNews())
- {
- qDebug() << "Ignored request to reload news. Currently reloading already.";
- return;
- }
-
- qDebug() << "Reloading news.";
-
- NetJob* job = new NetJob("News RSS Feed");
- job->addNetAction(ByteArrayDownload::make(m_feedUrl));
- QObject::connect(job, &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished);
- QObject::connect(job, &NetJob::failed, this, &NewsChecker::rssDownloadFailed);
- m_newsNetJob.reset(job);
- job->start();
-}
-
-void NewsChecker::rssDownloadFinished()
-{
- // Parse the XML file and process the RSS feed entries.
- qDebug() << "Finished loading RSS feed.";
-
- QByteArray data;
- {
- ByteArrayDownloadPtr dl = std::dynamic_pointer_cast<ByteArrayDownload>(m_newsNetJob->first());
- data = dl->m_data;
- m_newsNetJob.reset();
- }
-
- QDomDocument doc;
- {
- // Stuff to store error info in.
- QString errorMsg = "Unknown error.";
- int errorLine = -1;
- int errorCol = -1;
-
- // Parse the XML.
- if (!doc.setContent(data, false, &errorMsg, &errorLine, &errorCol))
- {
- QString fullErrorMsg = QString("Error parsing RSS feed XML. %s at %d:%d.").arg(errorMsg, errorLine, errorCol);
- fail(fullErrorMsg);
- return;
- }
- }
-
- // If the parsing succeeded, read it.
- QDomNodeList items = doc.elementsByTagName("item");
- m_newsEntries.clear();
- for (int i = 0; i < items.length(); i++)
- {
- QDomElement element = items.at(i).toElement();
- NewsEntryPtr entry;
- entry.reset(new NewsEntry());
- QString errorMsg = "An unknown error occurred.";
- if (NewsEntry::fromXmlElement(element, entry.get(), &errorMsg))
- {
- qDebug() << "Loaded news entry" << entry->title;
- m_newsEntries.append(entry);
- }
- else
- {
- qWarning() << "Failed to load news entry at index" << i << ":" << errorMsg;
- }
- }
-
- succeed();
-}
-
-void NewsChecker::rssDownloadFailed(QString reason)
-{
- // Set an error message and fail.
- fail(tr("Failed to load news RSS feed:\n%1").arg(reason));
-}
-
-
-QList<NewsEntryPtr> NewsChecker::getNewsEntries() const
-{
- return m_newsEntries;
-}
-
-bool NewsChecker::isLoadingNews() const
-{
- return m_newsNetJob.get() != nullptr;
-}
-
-QString NewsChecker::getLastLoadErrorMsg() const
-{
- return m_lastLoadError;
-}
-
-void NewsChecker::succeed()
-{
- m_lastLoadError = "";
- qDebug() << "News loading succeeded.";
- m_newsNetJob.reset();
- emit newsLoaded();
-}
-
-void NewsChecker::fail(const QString& errorMsg)
-{
- m_lastLoadError = errorMsg;
- qDebug() << "Failed to load news:" << errorMsg;
- m_newsNetJob.reset();
- emit newsLoadingFailed(errorMsg);
-}
-
diff --git a/libraries/logic/news/NewsChecker.h b/libraries/logic/news/NewsChecker.h
deleted file mode 100644
index b8b90728..00000000
--- a/libraries/logic/news/NewsChecker.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QString>
-#include <QList>
-
-#include <net/NetJob.h>
-
-#include "NewsEntry.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT NewsChecker : public QObject
-{
- Q_OBJECT
-public:
- /*!
- * Constructs a news reader to read from the given RSS feed URL.
- */
- NewsChecker(const QString& feedUrl);
-
- /*!
- * Returns the error message for the last time the news was loaded.
- * Empty string if the last load was successful.
- */
- QString getLastLoadErrorMsg() const;
-
- /*!
- * Returns true if the news has been loaded successfully.
- */
- bool isNewsLoaded() const;
-
- //! True if the news is currently loading. If true, reloadNews() will do nothing.
- bool isLoadingNews() const;
-
- /*!
- * Returns a list of news entries.
- */
- QList<NewsEntryPtr> getNewsEntries() const;
-
- /*!
- * Reloads the news from the website's RSS feed.
- * If the news is already loading, this does nothing.
- */
- void Q_SLOT reloadNews();
-
-signals:
- /*!
- * Signal fired after the news has finished loading.
- */
- void newsLoaded();
-
- /*!
- * Signal fired after the news fails to load.
- */
- void newsLoadingFailed(QString errorMsg);
-
-protected slots:
- void rssDownloadFinished();
- void rssDownloadFailed(QString reason);
-
-protected:
- //! The URL for the RSS feed to fetch.
- QString m_feedUrl;
-
- //! List of news entries.
- QList<NewsEntryPtr> m_newsEntries;
-
- //! The network job to use to load the news.
- NetJobPtr m_newsNetJob;
-
- //! True if news has been loaded.
- bool m_loadedNews;
-
- /*!
- * Gets the error message that was given last time the news was loaded.
- * If the last news load succeeded, this will be an empty string.
- */
- QString m_lastLoadError;
-
-
- /*!
- * Emits newsLoaded() and sets m_lastLoadError to empty string.
- */
- void Q_SLOT succeed();
-
- /*!
- * Emits newsLoadingFailed() and sets m_lastLoadError to the given message.
- */
- void Q_SLOT fail(const QString& errorMsg);
-};
-
diff --git a/libraries/logic/news/NewsEntry.cpp b/libraries/logic/news/NewsEntry.cpp
deleted file mode 100644
index 79abbaa3..00000000
--- a/libraries/logic/news/NewsEntry.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Copyright 2013-2015 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 "NewsEntry.h"
-
-#include <QDomNodeList>
-#include <QVariant>
-
-NewsEntry::NewsEntry(QObject* parent) :
- QObject(parent)
-{
- this->title = tr("Untitled");
- this->content = tr("No content.");
- this->link = "";
- this->author = tr("Unknown Author");
- this->pubDate = QDateTime::currentDateTime();
-}
-
-NewsEntry::NewsEntry(const QString& title, const QString& content, const QString& link, const QString& author, const QDateTime& pubDate, QObject* parent) :
- QObject(parent)
-{
- this->title = title;
- this->content = content;
- this->link = link;
- this->author = author;
- this->pubDate = pubDate;
-}
-
-/*!
- * Gets the text content of the given child element as a QVariant.
- */
-inline QString childValue(const QDomElement& element, const QString& childName, QString defaultVal="")
-{
- QDomNodeList nodes = element.elementsByTagName(childName);
- if (nodes.count() > 0)
- {
- QDomElement element = nodes.at(0).toElement();
- return element.text();
- }
- else
- {
- return defaultVal;
- }
-}
-
-bool NewsEntry::fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg)
-{
- QString title = childValue(element, "title", tr("Untitled"));
- QString content = childValue(element, "description", tr("No content."));
- QString link = childValue(element, "link");
- QString author = childValue(element, "dc:creator", tr("Unknown Author"));
- QString pubDateStr = childValue(element, "pubDate");
-
- // FIXME: For now, we're just ignoring timezones. We assume that all time zones in the RSS feed are the same.
- QString dateFormat("ddd, dd MMM yyyy hh:mm:ss");
- QDateTime pubDate = QDateTime::fromString(pubDateStr, dateFormat);
-
- entry->title = title;
- entry->content = content;
- entry->link = link;
- entry->author = author;
- entry->pubDate = pubDate;
- return true;
-}
-
diff --git a/libraries/logic/news/NewsEntry.h b/libraries/logic/news/NewsEntry.h
deleted file mode 100644
index adb79e8f..00000000
--- a/libraries/logic/news/NewsEntry.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QString>
-#include <QDomElement>
-#include <QDateTime>
-
-#include <memory>
-
-class NewsEntry : public QObject
-{
- Q_OBJECT
-
-public:
- /*!
- * Constructs an empty news entry.
- */
- explicit NewsEntry(QObject* parent=0);
-
- /*!
- * Constructs a new news entry.
- * Note that content may contain HTML.
- */
- NewsEntry(const QString& title, const QString& content, const QString& link, const QString& author, const QDateTime& pubDate, QObject* parent=0);
-
- /*!
- * Attempts to load information from the given XML element into the given news entry pointer.
- * If this fails, the function will return false and store an error message in the errorMsg pointer.
- */
- static bool fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg=0);
-
-
- //! The post title.
- QString title;
-
- //! The post's content. May contain HTML.
- QString content;
-
- //! URL to the post.
- QString link;
-
- //! The post's author.
- QString author;
-
- //! The date and time that this post was published.
- QDateTime pubDate;
-};
-
-typedef std::shared_ptr<NewsEntry> NewsEntryPtr;
-
diff --git a/libraries/logic/notifications/NotificationChecker.cpp b/libraries/logic/notifications/NotificationChecker.cpp
deleted file mode 100644
index ab2570b7..00000000
--- a/libraries/logic/notifications/NotificationChecker.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "NotificationChecker.h"
-
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QDebug>
-
-#include "Env.h"
-#include "net/CacheDownload.h"
-
-
-NotificationChecker::NotificationChecker(QObject *parent)
- : QObject(parent)
-{
-}
-
-void NotificationChecker::setNotificationsUrl(const QUrl &notificationsUrl)
-{
- m_notificationsUrl = notificationsUrl;
-}
-
-void NotificationChecker::setApplicationChannel(QString channel)
-{
- m_appVersionChannel = channel;
-}
-
-void NotificationChecker::setApplicationFullVersion(QString version)
-{
- m_appFullVersion = version;
-}
-
-void NotificationChecker::setApplicationPlatform(QString platform)
-{
- m_appPlatform = platform;
-}
-
-QList<NotificationChecker::NotificationEntry> NotificationChecker::notificationEntries() const
-{
- return m_entries;
-}
-
-void NotificationChecker::checkForNotifications()
-{
- if (!m_notificationsUrl.isValid())
- {
- qCritical() << "Failed to check for notifications. No notifications URL set."
- << "If you'd like to use MultiMC's notification system, please pass the "
- "URL to CMake at compile time.";
- return;
- }
- if (m_checkJob)
- {
- return;
- }
- m_checkJob.reset(new NetJob("Checking for notifications"));
- auto entry = ENV.metacache()->resolveEntry("root", "notifications.json");
- entry->setStale(true);
- m_checkJob->addNetAction(m_download = CacheDownload::make(m_notificationsUrl, entry));
- connect(m_download.get(), &CacheDownload::succeeded, this,
- &NotificationChecker::downloadSucceeded);
- m_checkJob->start();
-}
-
-void NotificationChecker::downloadSucceeded(int)
-{
- m_entries.clear();
-
- QFile file(m_download->getTargetFilepath());
- if (file.open(QFile::ReadOnly))
- {
- QJsonArray root = QJsonDocument::fromJson(file.readAll()).array();
- for (auto it = root.begin(); it != root.end(); ++it)
- {
- QJsonObject obj = (*it).toObject();
- NotificationEntry entry;
- entry.id = obj.value("id").toDouble();
- entry.message = obj.value("message").toString();
- entry.channel = obj.value("channel").toString();
- entry.platform = obj.value("platform").toString();
- entry.from = obj.value("from").toString();
- entry.to = obj.value("to").toString();
- const QString type = obj.value("type").toString("critical");
- if (type == "critical")
- {
- entry.type = NotificationEntry::Critical;
- }
- else if (type == "warning")
- {
- entry.type = NotificationEntry::Warning;
- }
- else if (type == "information")
- {
- entry.type = NotificationEntry::Information;
- }
- if(entryApplies(entry))
- m_entries.append(entry);
- }
- }
-
- m_checkJob.reset();
-
- emit notificationCheckFinished();
-}
-
-bool versionLessThan(const QString &v1, const QString &v2)
-{
- QStringList l1 = v1.split('.');
- QStringList l2 = v2.split('.');
- while (!l1.isEmpty() && !l2.isEmpty())
- {
- int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt();
- int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt();
- if (one != two)
- {
- return one < two;
- }
- }
- return false;
-}
-
-bool NotificationChecker::entryApplies(const NotificationChecker::NotificationEntry& entry) const
-{
- bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel;
- bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform;
- bool fromApplies =
- entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from);
- bool toApplies =
- entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion);
- return channelApplies && platformApplies && fromApplies && toApplies;
-}
diff --git a/libraries/logic/notifications/NotificationChecker.h b/libraries/logic/notifications/NotificationChecker.h
deleted file mode 100644
index a2d92ab9..00000000
--- a/libraries/logic/notifications/NotificationChecker.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-#include <QObject>
-
-#include "net/NetJob.h"
-#include "net/CacheDownload.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT NotificationChecker : public QObject
-{
- Q_OBJECT
-
-public:
- explicit NotificationChecker(QObject *parent = 0);
-
- void setNotificationsUrl(const QUrl &notificationsUrl);
- void setApplicationPlatform(QString platform);
- void setApplicationChannel(QString channel);
- void setApplicationFullVersion(QString version);
-
- struct NotificationEntry
- {
- int id;
- QString message;
- enum
- {
- Critical,
- Warning,
- Information
- } type;
- QString channel;
- QString platform;
- QString from;
- QString to;
- };
-
- QList<NotificationEntry> notificationEntries() const;
-
-public
-slots:
- void checkForNotifications();
-
-private
-slots:
- void downloadSucceeded(int);
-
-signals:
- void notificationCheckFinished();
-
-private:
- bool entryApplies(const NotificationEntry &entry) const;
-
-private:
- QList<NotificationEntry> m_entries;
- QUrl m_notificationsUrl;
- NetJobPtr m_checkJob;
- CacheDownloadPtr m_download;
-
- QString m_appVersionChannel;
- QString m_appPlatform;
- QString m_appFullVersion;
-};
diff --git a/libraries/logic/pathmatcher/FSTreeMatcher.h b/libraries/logic/pathmatcher/FSTreeMatcher.h
deleted file mode 100644
index a5bed57c..00000000
--- a/libraries/logic/pathmatcher/FSTreeMatcher.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include "IPathMatcher.h"
-#include <SeparatorPrefixTree.h>
-#include <QRegularExpression>
-
-class FSTreeMatcher : public IPathMatcher
-{
-public:
- virtual ~FSTreeMatcher() {};
- FSTreeMatcher(SeparatorPrefixTree<'/'> & tree) : m_fsTree(tree)
- {
- }
-
- virtual bool matches(const QString &string) const override
- {
- return m_fsTree.covers(string);
- }
-
- SeparatorPrefixTree<'/'> & m_fsTree;
-};
diff --git a/libraries/logic/pathmatcher/IPathMatcher.h b/libraries/logic/pathmatcher/IPathMatcher.h
deleted file mode 100644
index 1d410947..00000000
--- a/libraries/logic/pathmatcher/IPathMatcher.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-#include <memory>
-
-class IPathMatcher
-{
-public:
- typedef std::shared_ptr<IPathMatcher> Ptr;
-
-public:
- virtual ~IPathMatcher(){};
- virtual bool matches(const QString &string) const = 0;
-};
diff --git a/libraries/logic/pathmatcher/MultiMatcher.h b/libraries/logic/pathmatcher/MultiMatcher.h
deleted file mode 100644
index 91f70aa4..00000000
--- a/libraries/logic/pathmatcher/MultiMatcher.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "IPathMatcher.h"
-#include <SeparatorPrefixTree.h>
-#include <QRegularExpression>
-
-class MultiMatcher : public IPathMatcher
-{
-public:
- virtual ~MultiMatcher() {};
- MultiMatcher()
- {
- }
- MultiMatcher &add(Ptr add)
- {
- m_matchers.append(add);
- return *this;
- }
-
- virtual bool matches(const QString &string) const override
- {
- for(auto iter: m_matchers)
- {
- if(iter->matches(string))
- {
- return true;
- }
- }
- return false;
- }
-
- QList<Ptr> m_matchers;
-};
diff --git a/libraries/logic/pathmatcher/RegexpMatcher.h b/libraries/logic/pathmatcher/RegexpMatcher.h
deleted file mode 100644
index da552123..00000000
--- a/libraries/logic/pathmatcher/RegexpMatcher.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "IPathMatcher.h"
-#include <QRegularExpression>
-
-class RegexpMatcher : public IPathMatcher
-{
-public:
- virtual ~RegexpMatcher() {};
- RegexpMatcher(const QString &regexp)
- {
- m_regexp.setPattern(regexp);
- m_onlyFilenamePart = !regexp.contains('/');
- }
-
- RegexpMatcher &caseSensitive(bool cs = true)
- {
- if(cs)
- {
- m_regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
- }
- else
- {
- m_regexp.setPatternOptions(QRegularExpression::NoPatternOption);
- }
- return *this;
- }
-
- virtual bool matches(const QString &string) const override
- {
- if(m_onlyFilenamePart)
- {
- auto slash = string.lastIndexOf('/');
- if(slash != -1)
- {
- auto part = string.mid(slash + 1);
- return m_regexp.match(part).hasMatch();
- }
- }
- return m_regexp.match(string).hasMatch();
- }
- QRegularExpression m_regexp;
- bool m_onlyFilenamePart = false;
-};
diff --git a/libraries/logic/resources/Resource.cpp b/libraries/logic/resources/Resource.cpp
deleted file mode 100644
index e95675d7..00000000
--- a/libraries/logic/resources/Resource.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-#include "Resource.h"
-
-#include <QDebug>
-
-#include "ResourceObserver.h"
-#include "ResourceHandler.h"
-
-// definition of static members of Resource
-QMap<QString, std::function<std::shared_ptr<ResourceHandler>(const QString &)>> Resource::m_handlers;
-QMap<QPair<int, int>, std::function<QVariant(QVariant)>> Resource::m_transfomers;
-QMap<QString, std::weak_ptr<Resource>> Resource::m_resources;
-
-struct NullResourceResult {};
-Q_DECLARE_METATYPE(NullResourceResult)
-class NullResourceHandler : public ResourceHandler
-{
-public:
- explicit NullResourceHandler()
- {
- setResult(QVariant::fromValue<NullResourceResult>(NullResourceResult()));
- }
-};
-
-Resource::Resource(const QString &resource)
- : m_resource(resource)
-{
- if (!resource.isEmpty())
- {
- // a valid resource identifier has the format <id>:<data>
- Q_ASSERT(resource.contains(':'));
- // "parse" the resource identifier into id and data
- const QString resourceId = resource.left(resource.indexOf(':'));
- const QString resourceData = resource.mid(resource.indexOf(':') + 1);
-
- // create and set up the handler
- Q_ASSERT(m_handlers.contains(resourceId));
- m_handler = m_handlers.value(resourceId)(resourceData);
- }
- else
- {
- m_handler = std::make_shared<NullResourceHandler>();
- }
-
- Q_ASSERT(m_handler);
- m_handler->init(m_handler);
- m_handler->setResource(this);
-}
-Resource::~Resource()
-{
- qDeleteAll(m_observers);
-}
-
-Resource::Ptr Resource::create(const QString &resource, Ptr placeholder)
-{
- const QString storageId = storageIdentifier(resource, placeholder);
-
- // do we already have a resource? even if m_resources contains it it might not be valid any longer (weak_ptr)
- Resource::Ptr ptr = m_resources.contains(storageId)
- ? m_resources.value(storageId).lock()
- : nullptr;
- // did we have one? and is it still valid?
- if (!ptr)
- {
- /* We don't want Resource to have a public constructor, but std::make_shared needs it,
- * so we create a subclass of Resource here that exposes the constructor as public.
- * The alternative would be making the allocator for std::make_shared a friend, but it
- * differs between different STL implementations, so that would be a pain.
- */
- struct ConstructableResource : public Resource
- {
- explicit ConstructableResource(const QString &resource)
- : Resource(resource) {}
- };
- ptr = std::make_shared<ConstructableResource>(resource);
- ptr->m_placeholder = placeholder;
- m_resources.insert(storageId, ptr);
- }
- return ptr;
-}
-
-Resource::Ptr Resource::applyTo(ResourceObserver *observer)
-{
- m_observers.append(observer);
- observer->setSource(shared_from_this()); // give the observer a shared_ptr for us so we don't get deleted
- observer->resourceUpdated(); // ask the observer to poll us immediently, we might already have data
- return shared_from_this(); // allow chaining
-}
-Resource::Ptr Resource::applyTo(QObject *target, const char *property)
-{
- // the cast to ResourceObserver* is required to ensure the right overload gets choosen,
- // since QObjectResourceObserver also inherits from QObject
- return applyTo(static_cast<ResourceObserver *>(new QObjectResourceObserver(target, property)));
-}
-
-QVariant Resource::getResourceInternal(const int typeId) const
-{
- // no result (yet), but a placeholder? delegate to the placeholder.
- if (m_handler->result().isNull() && m_placeholder)
- {
- return m_placeholder->getResourceInternal(typeId);
- }
- const QVariant variant = m_handler->result();
- const auto typePair = qMakePair(int(variant.type()), typeId);
-
- // do we have an explicit transformer? use it.
- if (m_transfomers.contains(typePair))
- {
- return m_transfomers.value(typePair)(variant);
- }
- else
- {
- // we do not have an explicit transformer, so we just pass the QVariant, which will automatically
- // transform some types for us (different numbers to each other etc.)
- return variant;
- }
-}
-
-void Resource::reportResult()
-{
- for (ResourceObserver *observer : m_observers)
- {
- observer->resourceUpdated();
- }
-}
-void Resource::reportFailure(const QString &reason)
-{
- for (ResourceObserver *observer : m_observers)
- {
- observer->setFailure(reason);
- }
-}
-void Resource::reportProgress(const int progress)
-{
- for (ResourceObserver *observer : m_observers)
- {
- observer->setProgress(progress);
- }
-}
-
-void Resource::notifyObserverDeleted(ResourceObserver *observer)
-{
- m_observers.removeAll(observer);
-}
-
-QString Resource::storageIdentifier(const QString &id, Resource::Ptr placeholder)
-{
- if (placeholder)
- {
- return id + '#' + storageIdentifier(placeholder->m_resource, placeholder->m_placeholder);
- }
- else
- {
- return id;
- }
-}
diff --git a/libraries/logic/resources/Resource.h b/libraries/logic/resources/Resource.h
deleted file mode 100644
index 63e97b88..00000000
--- a/libraries/logic/resources/Resource.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QMap>
-#include <QVariant>
-#include <functional>
-#include <memory>
-
-#include "ResourceObserver.h"
-#include "TypeMagic.h"
-
-#include "multimc_logic_export.h"
-
-class ResourceHandler;
-
-/** Frontend class for resources
- *
- * Usage:
- * Resource::create("icon:noaccount")->applyTo(accountsAction);
- * Resource::create("web:http://asdf.com/image.png")->applyTo(imageLbl)->placeholder(Resource::create("icon:loading"));
- *
- * Memory management:
- * Resource caches ResourcePtrs using weak pointers, so while a resource is still existing
- * when a new resource is created the resources will be the same (including the same handler).
- *
- * ResourceObservers keep a shared pointer to the resource, as does the Resource itself to it's
- * placeholder (if present). This means a resource stays valid while it's still used ("applied to" etc.)
- * by something. When nothing uses it anymore it gets deleted.
- *
- * @note Always pass resource around using Resource::Ptr! Copy and move constructors are disabled for a reason.
- */
-class MULTIMC_LOGIC_EXPORT Resource : public std::enable_shared_from_this<Resource>
-{
- // only allow creation from Resource::create and disallow passing around non-pointers
- explicit Resource(const QString &resource);
- Resource(const Resource &) = delete;
- Resource(Resource &&) = delete;
-public:
- using Ptr = std::shared_ptr<Resource>;
-
- ~Resource();
-
- /// The returned pointer needs to be stored until either Resource::applyTo or Resource::then is called, or it is passed as
- /// a placeholder to Resource::create itself.
- static Ptr create(const QString &resource, Ptr placeholder = nullptr);
-
- /// Use these functions to specify what should happen when e.g. the resource changes
- Ptr applyTo(ResourceObserver *observer);
- Ptr applyTo(QObject *target, const char *property = nullptr);
- template<typename Func>
- Ptr then(Func &&func)
- {
- // Arg will be the functions argument with references and cv-qualifiers (const, volatile) removed
- using Arg = TypeMagic::CleanType<typename TypeMagic::Function<Func>::Argument>;
- // Ret will be the functions return type
- using Ret = typename TypeMagic::Function<Func>::ReturnType;
-
- // FunctionResourceObserver<ReturnType, ArgumentType, FunctionSignature>
- return applyTo(new FunctionResourceObserver<Ret, Arg, Func>(std::forward<Func>(func)));
- }
-
- /// Retrieve the currently active resource. If it's type is different from T a conversion will be attempted.
- template<typename T>
- T getResource() const { return getResourceInternal(qMetaTypeId<T>()).template value<T>(); }
-
- /// @internal Used by ResourceObserver and ResourceProxyModel
- QVariant getResourceInternal(const int typeId) const;
-
- /** Register a new ResourceHandler. T needs to inherit from ResourceHandler
- * Usage: Resource::registerHandler<MyResourceHandler>("myid");
- */
- template<typename T>
- static void registerHandler(const QString &id)
- {
- m_handlers.insert(id, [](const QString &res) { return std::make_shared<T>(res); });
- }
- /** Register a new resource transformer
- * Resource transformers are functions that are responsible for converting between different types,
- * for example converting from a QByteArray to a QPixmap. They are registered "externally" because not
- * all types might be available in this library, for example gui types like QPixmap.
- *
- * Usage: Resource::registerTransformer([](const InputType &type) { return OutputType(type); });
- * This assumes that OutputType has a constructor that takes InputType as an argument. More
- * complicated transformers can of course also be registered.
- *
- * When a ResourceObserver requests a type that's different from the actual resource type, a matching
- * transformer will be looked up from the list of transformers.
- * @note Only one-stage transforms will be performed (you can't registerTransformers for QString => int
- * and int => float and expect QString to automatically be transformed into a float.
- */
- template<typename Func>
- static void registerTransformer(Func &&func)
- {
- using Out = typename TypeMagic::Function<Func>::ReturnType;
- using In = TypeMagic::CleanType<typename TypeMagic::Function<Func>::Argument>;
- static_assert(!std::is_same<Out, In>::value, "It does not make sense to transform a value to itself");
- m_transfomers.insert(qMakePair(qMetaTypeId<In>(), qMetaTypeId<Out>()), [func](const QVariant &in)
- {
- return QVariant::fromValue<Out>(func(in.value<In>()));
- });
- }
-
-private: // half private, implementation details
- friend class ResourceHandler;
- // the following three functions are called by ResourceHandlers
- /** Notifies the observers. They will call Resource::getResourceInternal which will call ResourceHandler::result
- * or delegate to it's placeholder.
- */
- void reportResult();
- void reportFailure(const QString &reason);
- void reportProgress(const int progress);
-
- friend class ResourceObserver;
- /// Removes observer from the list of observers so that we don't attempt to notify something that doesn't exist
- void notifyObserverDeleted(ResourceObserver *observer);
-
-private: // truly private
- QList<ResourceObserver *> m_observers;
- std::shared_ptr<ResourceHandler> m_handler = nullptr;
- Ptr m_placeholder = nullptr;
- const QString m_resource;
-
- static QString storageIdentifier(const QString &id, Ptr placeholder = nullptr);
- QString storageIdentifier() const;
-
- // a list of resource handler factories, registered using registerHandler
- static QMap<QString, std::function<std::shared_ptr<ResourceHandler>(const QString &)>> m_handlers;
- // a list of resource transformers, registered using registerTransformer
- static QMap<QPair<int, int>, std::function<QVariant(QVariant)>> m_transfomers;
- // a list of resources so that we can reuse them
- static QMap<QString, std::weak_ptr<Resource>> m_resources;
-};
diff --git a/libraries/logic/resources/ResourceHandler.cpp b/libraries/logic/resources/ResourceHandler.cpp
deleted file mode 100644
index 46a4422c..00000000
--- a/libraries/logic/resources/ResourceHandler.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "ResourceHandler.h"
-
-#include "Resource.h"
-
-void ResourceHandler::setResult(const QVariant &result)
-{
- m_result = result;
- if (m_resource)
- {
- m_resource->reportResult();
- }
-}
-
-void ResourceHandler::setFailure(const QString &reason)
-{
- if (m_resource)
- {
- m_resource->reportFailure(reason);
- }
-}
-
-void ResourceHandler::setProgress(const int progress)
-{
- if (m_resource)
- {
- m_resource->reportProgress(progress);
- }
-}
diff --git a/libraries/logic/resources/ResourceHandler.h b/libraries/logic/resources/ResourceHandler.h
deleted file mode 100644
index f09d8904..00000000
--- a/libraries/logic/resources/ResourceHandler.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <QVariant>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class Resource;
-
-/** Base class for things that can retrieve a resource.
- *
- * Subclass, provide a constructor that takes a single QString as argument, and
- * call Resource::registerHandler<MyResourceHandler>("<id>"), where <id> is the
- * prefix of the resource ("web", "icon", etc.)
- */
-class MULTIMC_LOGIC_EXPORT ResourceHandler
-{
-public:
- virtual ~ResourceHandler() {}
-
- void setResource(Resource *resource) { m_resource = resource; }
- /// reimplement this if you need to do something after you have been put in a shared pointer
- // we do this instead of inheriting from std::enable_shared_from_this
- virtual void init(std::shared_ptr<ResourceHandler>&) {}
-
- QVariant result() const { return m_result; }
-
-protected: // use these methods to notify the resource of changes
- void setResult(const QVariant &result);
- void setFailure(const QString &reason);
- void setProgress(const int progress);
-
-private:
- QVariant m_result;
- Resource *m_resource = nullptr;
-};
diff --git a/libraries/logic/resources/ResourceObserver.cpp b/libraries/logic/resources/ResourceObserver.cpp
deleted file mode 100644
index 4f168fd2..00000000
--- a/libraries/logic/resources/ResourceObserver.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "ResourceObserver.h"
-
-#include <QDebug>
-
-#include "Resource.h"
-
-static const char *defaultPropertyForTarget(QObject *target)
-{
- if (target->inherits("QLabel"))
- {
- return "pixmap";
- }
- else if (target->inherits("QAction") ||
- target->inherits("QMenu") ||
- target->inherits("QAbstractButton"))
- {
- return "icon";
- }
- // for unit tests
- else if (target->inherits("DummyObserverObject"))
- {
- return "property";
- }
- else
- {
- Q_ASSERT_X(false, "ResourceObserver.cpp: defaultPropertyForTarget", "Unrecognized QObject subclass");
- return nullptr;
- }
-}
-
-QObjectResourceObserver::QObjectResourceObserver(QObject *target, const char *property)
- : QObject(target), m_target(target)
-{
- const QMetaObject *mo = m_target->metaObject();
- m_property = mo->property(mo->indexOfProperty(
- property ?
- property
- : defaultPropertyForTarget(target)));
-}
-void QObjectResourceObserver::resourceUpdated()
-{
- m_property.write(m_target, getInternal(m_property.type()));
-}
-
-
-ResourceObserver::~ResourceObserver()
-{
- m_resource->notifyObserverDeleted(this);
-}
-
-QVariant ResourceObserver::getInternal(const int typeId) const
-{
- Q_ASSERT(m_resource);
- return m_resource->getResourceInternal(typeId);
-}
diff --git a/libraries/logic/resources/ResourceObserver.h b/libraries/logic/resources/ResourceObserver.h
deleted file mode 100644
index c42e41ba..00000000
--- a/libraries/logic/resources/ResourceObserver.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#pragma once
-
-#include <memory>
-#include <functional>
-
-#include <QObject>
-#include <QMetaProperty>
-#include "multimc_logic_export.h"
-
-class QVariant;
-class Resource;
-
-/// Base class for things that can use a resource
-class MULTIMC_LOGIC_EXPORT ResourceObserver
-{
-public:
- virtual ~ResourceObserver();
-
-protected: // these methods are called by the Resource when something changes
- virtual void resourceUpdated() = 0;
- virtual void setFailure(const QString &) {}
- virtual void setProgress(const int) {}
-
-private:
- friend class Resource;
- void setSource(std::shared_ptr<Resource> resource) { m_resource = resource; }
-
-protected:
- template<typename T>
- T get() const { return getInternal(qMetaTypeId<T>()).template value<T>(); }
- QVariant getInternal(const int typeId) const;
-
-private:
- std::shared_ptr<Resource> m_resource;
-};
-
-/** Observer for QObject properties
- *
- * Give it a target and the name of a property, and that property will be set when the resource changes.
- *
- * If no name is given an attempt to find a default property for some common classes is done.
- */
-class MULTIMC_LOGIC_EXPORT QObjectResourceObserver : public QObject, public ResourceObserver
-{
-public:
- explicit QObjectResourceObserver(QObject *target, const char *property = nullptr);
-
- void resourceUpdated() override;
-
-private:
- QObject *m_target;
- QMetaProperty m_property;
-};
-
-/** Observer for functions, lambdas etc.
- * Template arguments:
- * * We need Ret and Arg in order to create the std::function
- * * We need Func in order to std::forward the function
- */
-template <typename Ret, typename Arg, typename Func>
-class FunctionResourceObserver : public ResourceObserver
-{
- std::function<Ret(Arg)> m_function;
-public:
- template <typename T>
- explicit FunctionResourceObserver(T &&func)
- : m_function(std::forward<Func>(func)) {}
-
- void resourceUpdated() override
- {
- m_function(get<Arg>());
- }
-};
diff --git a/libraries/logic/resources/ResourceProxyModel.cpp b/libraries/logic/resources/ResourceProxyModel.cpp
deleted file mode 100644
index f026d9a9..00000000
--- a/libraries/logic/resources/ResourceProxyModel.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-#include "ResourceProxyModel.h"
-
-#include <QItemSelectionRange>
-
-#include "Resource.h"
-#include "ResourceObserver.h"
-
-class ModelResourceObserver : public ResourceObserver
-{
-public:
- explicit ModelResourceObserver(const QModelIndex &index, const int role)
- : m_index(index), m_role(role)
- {
- qRegisterMetaType<QVector<int>>("QVector<int>");
- }
-
- void resourceUpdated() override
- {
- if (m_index.isValid())
- {
- // the resource changed, pretend to be the model and notify the views of the update. they will re-poll the model which will return the new resource value
- QMetaObject::invokeMethod(const_cast<QAbstractItemModel *>(m_index.model()),
- "dataChanged", Qt::QueuedConnection,
- Q_ARG(QModelIndex, m_index), Q_ARG(QModelIndex, m_index), Q_ARG(QVector<int>, QVector<int>() << m_role));
- }
- }
-
-private:
- QPersistentModelIndex m_index;
- int m_role;
-};
-
-ResourceProxyModel::ResourceProxyModel(const int resultTypeId, QObject *parent)
- : QIdentityProxyModel(parent), m_resultTypeId(resultTypeId)
-{
-}
-
-QVariant ResourceProxyModel::data(const QModelIndex &proxyIndex, int role) const
-{
- const QModelIndex mapped = mapToSource(proxyIndex);
- // valid cell that's a Qt::DecorationRole and that contains a non-empty string
- if (mapped.isValid() && role == Qt::DecorationRole && !mapToSource(proxyIndex).data(role).toString().isEmpty())
- {
- // do we already have a resource for this index?
- if (!m_resources.contains(mapped))
- {
- Resource::Ptr placeholder;
- const QVariant placeholderIdentifier = mapped.data(PlaceholderRole);
- if (!placeholderIdentifier.isNull() && placeholderIdentifier.type() == QVariant::String)
- {
- placeholder = Resource::create(placeholderIdentifier.toString());
- }
-
- // create the Resource and apply the observer for models
- Resource::Ptr res = Resource::create(mapToSource(proxyIndex).data(role).toString(), placeholder)
- ->applyTo(new ModelResourceObserver(proxyIndex, role));
-
- m_resources.insert(mapped, res);
- }
-
- return m_resources.value(mapped)->getResourceInternal(m_resultTypeId);
- }
- // otherwise fall back to the source model
- return mapped.data(role);
-}
-
-void ResourceProxyModel::setSourceModel(QAbstractItemModel *model)
-{
- if (sourceModel())
- {
- disconnect(sourceModel(), 0, this, 0);
- }
- if (model)
- {
- connect(model, &QAbstractItemModel::dataChanged, this, [this](const QModelIndex &tl, const QModelIndex &br, const QVector<int> &roles)
- {
- // invalidate resources so that they will be re-created
- if (roles.contains(Qt::DecorationRole) || roles.contains(PlaceholderRole) || roles.isEmpty())
- {
- const QItemSelectionRange range(tl, br);
- for (const QModelIndex &index : range.indexes())
- {
- m_resources.remove(index);
- }
- }
- });
- }
- QIdentityProxyModel::setSourceModel(model);
-}
diff --git a/libraries/logic/resources/ResourceProxyModel.h b/libraries/logic/resources/ResourceProxyModel.h
deleted file mode 100644
index 98a3dbd1..00000000
--- a/libraries/logic/resources/ResourceProxyModel.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include <QIdentityProxyModel>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-/// Convenience proxy model that transforms resource identifiers (strings) for Qt::DecorationRole into other types.
-class MULTIMC_LOGIC_EXPORT ResourceProxyModel : public QIdentityProxyModel
-{
- Q_OBJECT
-public:
- // resultTypeId is found using qMetaTypeId<T>()
- explicit ResourceProxyModel(const int resultTypeId, QObject *parent = nullptr);
-
- enum
- {
- // provide this role from your model if you want to show a placeholder
- PlaceholderRole = Qt::UserRole + 0xabc // some random offset to not collide with other stuff
- };
-
- QVariant data(const QModelIndex &proxyIndex, int role) const override;
- void setSourceModel(QAbstractItemModel *model) override;
-
- /// Helper function, usage: m_view->setModel(ResourceProxyModel::mixin<QIcon>(m_model));
- template <typename T>
- static QAbstractItemModel *mixin(QAbstractItemModel *model)
- {
- ResourceProxyModel *proxy = new ResourceProxyModel(qMetaTypeId<T>(), model);
- proxy->setSourceModel(model);
- return proxy;
- }
-
-private:
- // mutable because it needs to be available from the const data()
- mutable QMap<QPersistentModelIndex, std::shared_ptr<class Resource>> m_resources;
-
- const int m_resultTypeId;
-};
diff --git a/libraries/logic/screenshots/ImgurAlbumCreation.cpp b/libraries/logic/screenshots/ImgurAlbumCreation.cpp
deleted file mode 100644
index e009ef4d..00000000
--- a/libraries/logic/screenshots/ImgurAlbumCreation.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "ImgurAlbumCreation.h"
-
-#include <QNetworkRequest>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QUrl>
-#include <QStringList>
-
-#include "net/URLConstants.h"
-#include "Env.h"
-#include <QDebug>
-
-ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenshotPtr> screenshots) : NetAction(), m_screenshots(screenshots)
-{
- m_url = URLConstants::IMGUR_BASE_URL + "album.json";
- m_status = Job_NotStarted;
-}
-
-void ImgurAlbumCreation::start()
-{
- m_status = Job_InProgress;
- QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
- request.setRawHeader("Accept", "application/json");
-
- QStringList ids;
- for (auto shot : m_screenshots)
- {
- ids.append(shot->m_imgurId);
- }
-
- const QByteArray data = "ids=" + ids.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden";
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->post(request, data);
-
- m_reply.reset(rep);
- connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress);
- connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
-}
-void ImgurAlbumCreation::downloadError(QNetworkReply::NetworkError error)
-{
- qDebug() << m_reply->errorString();
- m_status = Job_Failed;
-}
-void ImgurAlbumCreation::downloadFinished()
-{
- if (m_status != Job_Failed)
- {
- QByteArray data = m_reply->readAll();
- m_reply.reset();
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- qDebug() << jsonError.errorString();
- emit failed(m_index_within_job);
- return;
- }
- auto object = doc.object();
- if (!object.value("success").toBool())
- {
- qDebug() << doc.toJson();
- emit failed(m_index_within_job);
- return;
- }
- m_deleteHash = object.value("data").toObject().value("deletehash").toString();
- m_id = object.value("data").toObject().value("id").toString();
- m_status = Job_Finished;
- emit succeeded(m_index_within_job);
- return;
- }
- else
- {
- qDebug() << m_reply->readAll();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
-}
-void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
diff --git a/libraries/logic/screenshots/ImgurAlbumCreation.h b/libraries/logic/screenshots/ImgurAlbumCreation.h
deleted file mode 100644
index 469174e4..00000000
--- a/libraries/logic/screenshots/ImgurAlbumCreation.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-#include "net/NetAction.h"
-#include "Screenshot.h"
-
-#include "multimc_logic_export.h"
-
-typedef std::shared_ptr<class ImgurAlbumCreation> ImgurAlbumCreationPtr;
-class MULTIMC_LOGIC_EXPORT ImgurAlbumCreation : public NetAction
-{
-public:
- explicit ImgurAlbumCreation(QList<ScreenshotPtr> screenshots);
- static ImgurAlbumCreationPtr make(QList<ScreenshotPtr> screenshots)
- {
- return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots));
- }
-
- QString deleteHash() const
- {
- return m_deleteHash;
- }
- QString id() const
- {
- return m_id;
- }
-
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead()
- {
- }
-
-public
-slots:
- virtual void start();
-
-private:
- QList<ScreenshotPtr> m_screenshots;
-
- QString m_deleteHash;
- QString m_id;
-};
diff --git a/libraries/logic/screenshots/ImgurUpload.cpp b/libraries/logic/screenshots/ImgurUpload.cpp
deleted file mode 100644
index 48e0ec18..00000000
--- a/libraries/logic/screenshots/ImgurUpload.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "ImgurUpload.h"
-
-#include <QNetworkRequest>
-#include <QHttpMultiPart>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QHttpPart>
-#include <QFile>
-#include <QUrl>
-
-#include "net/URLConstants.h"
-#include "Env.h"
-#include <QDebug>
-
-ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot)
-{
- m_url = URLConstants::IMGUR_BASE_URL + "upload.json";
- m_status = Job_NotStarted;
-}
-
-void ImgurUpload::start()
-{
- finished = false;
- m_status = Job_InProgress;
- QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
- request.setRawHeader("Accept", "application/json");
-
- QFile f(m_shot->m_file.absoluteFilePath());
- if (!f.open(QFile::ReadOnly))
- {
- emit failed(m_index_within_job);
- return;
- }
-
- QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
- QHttpPart filePart;
- filePart.setBody(f.readAll().toBase64());
- filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
- filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\"");
- multipart->append(filePart);
- QHttpPart typePart;
- typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\"");
- typePart.setBody("base64");
- multipart->append(typePart);
- QHttpPart namePart;
- namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\"");
- namePart.setBody(m_shot->m_file.baseName().toUtf8());
- multipart->append(namePart);
-
- auto worker = ENV.qnam();
- QNetworkReply *rep = worker->post(request, multipart);
-
- m_reply.reset(rep);
- connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress);
- connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
-}
-void ImgurUpload::downloadError(QNetworkReply::NetworkError error)
-{
- qCritical() << "ImgurUpload failed with error" << m_reply->errorString() << "Server reply:\n" << m_reply->readAll();
- if(finished)
- {
- qCritical() << "Double finished ImgurUpload!";
- return;
- }
- m_status = Job_Failed;
- finished = true;
- m_reply.reset();
- emit failed(m_index_within_job);
-}
-void ImgurUpload::downloadFinished()
-{
- if(finished)
- {
- qCritical() << "Double finished ImgurUpload!";
- return;
- }
- QByteArray data = m_reply->readAll();
- m_reply.reset();
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- qDebug() << "imgur server did not reply with JSON" << jsonError.errorString();
- finished = true;
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- auto object = doc.object();
- if (!object.value("success").toBool())
- {
- qDebug() << "Screenshot upload not successful:" << doc.toJson();
- finished = true;
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- m_shot->m_imgurId = object.value("data").toObject().value("id").toString();
- m_shot->m_url = object.value("data").toObject().value("link").toString();
- m_status = Job_Finished;
- finished = true;
- emit succeeded(m_index_within_job);
- return;
-}
-void ImgurUpload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
-}
diff --git a/libraries/logic/screenshots/ImgurUpload.h b/libraries/logic/screenshots/ImgurUpload.h
deleted file mode 100644
index 0a766b8f..00000000
--- a/libraries/logic/screenshots/ImgurUpload.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-#include "net/NetAction.h"
-#include "Screenshot.h"
-
-#include "multimc_logic_export.h"
-
-typedef std::shared_ptr<class ImgurUpload> ImgurUploadPtr;
-class MULTIMC_LOGIC_EXPORT ImgurUpload : public NetAction
-{
-public:
- explicit ImgurUpload(ScreenshotPtr shot);
- static ImgurUploadPtr make(ScreenshotPtr shot)
- {
- return ImgurUploadPtr(new ImgurUpload(shot));
- }
-
-protected
-slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead()
- {
- }
-
-public
-slots:
- virtual void start();
-
-private:
- ScreenshotPtr m_shot;
- bool finished = true;
-};
diff --git a/libraries/logic/screenshots/Screenshot.h b/libraries/logic/screenshots/Screenshot.h
deleted file mode 100644
index b48cbe99..00000000
--- a/libraries/logic/screenshots/Screenshot.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include <QDateTime>
-#include <QString>
-#include <QFileInfo>
-#include <memory>
-
-struct ScreenShot
-{
- ScreenShot(QFileInfo file)
- {
- m_file = file;
- }
- QFileInfo m_file;
- QString m_url;
- QString m_imgurId;
-};
-
-typedef std::shared_ptr<ScreenShot> ScreenshotPtr;
diff --git a/libraries/logic/settings/INIFile.cpp b/libraries/logic/settings/INIFile.cpp
deleted file mode 100644
index 69a6b87e..00000000
--- a/libraries/logic/settings/INIFile.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Copyright 2013-2015 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 "settings/INIFile.h"
-#include <FileSystem.h>
-
-#include <QFile>
-#include <QTextStream>
-#include <QStringList>
-#include <QSaveFile>
-#include <QDebug>
-
-INIFile::INIFile()
-{
-}
-
-QString INIFile::unescape(QString orig)
-{
- QString out;
- QChar prev = 0;
- for(auto c: orig)
- {
- if(prev == '\\')
- {
- if(c == 'n')
- out += '\n';
- else if (c == 't')
- out += '\t';
- else
- out += c;
- prev = 0;
- }
- else
- {
- if(c == '\\')
- {
- prev = c;
- continue;
- }
- out += c;
- prev = 0;
- }
- }
- return out;
-}
-
-QString INIFile::escape(QString orig)
-{
- QString out;
- for(auto c: orig)
- {
- if(c == '\n')
- out += "\\n";
- else if (c == '\t')
- out += "\\t";
- else if(c == '\\')
- out += "\\\\";
- else
- out += c;
- }
- return out;
-}
-
-bool INIFile::saveFile(QString fileName)
-{
- QByteArray outArray;
- for (Iterator iter = begin(); iter != end(); iter++)
- {
- QString value = iter.value().toString();
- value = escape(value);
- outArray.append(iter.key().toUtf8());
- outArray.append('=');
- outArray.append(value.toUtf8());
- outArray.append('\n');
- }
-
- try
- {
- FS::write(fileName, outArray);
- }
- catch (Exception & e)
- {
- qCritical() << e.what();
- return false;
- }
-
- return true;
-}
-
-
-bool INIFile::loadFile(QString fileName)
-{
- QFile file(fileName);
- if (!file.open(QIODevice::ReadOnly))
- return false;
- bool success = loadFile(file.readAll());
- file.close();
- return success;
-}
-
-bool INIFile::loadFile(QByteArray file)
-{
- QTextStream in(file);
- in.setCodec("UTF-8");
-
- QStringList lines = in.readAll().split('\n');
- for (int i = 0; i < lines.count(); i++)
- {
- QString &lineRaw = lines[i];
- // Ignore comments.
- QString line = lineRaw.left(lineRaw.indexOf('#')).trimmed();
-
- int eqPos = line.indexOf('=');
- if (eqPos == -1)
- continue;
- QString key = line.left(eqPos).trimmed();
- QString valueStr = line.right(line.length() - eqPos - 1).trimmed();
-
- valueStr = unescape(valueStr);
-
- QVariant value(valueStr);
- this->operator[](key) = value;
- }
-
- return true;
-}
-
-QVariant INIFile::get(QString key, QVariant def) const
-{
- if (!this->contains(key))
- return def;
- else
- return this->operator[](key);
-}
-
-void INIFile::set(QString key, QVariant val)
-{
- this->operator[](key) = val;
-}
diff --git a/libraries/logic/settings/INIFile.h b/libraries/logic/settings/INIFile.h
deleted file mode 100644
index 5013eb2d..00000000
--- a/libraries/logic/settings/INIFile.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-#include <QVariant>
-#include <QIODevice>
-
-#include "multimc_logic_export.h"
-
-// Sectionless INI parser (for instance config files)
-class MULTIMC_LOGIC_EXPORT INIFile : public QMap<QString, QVariant>
-{
-public:
- explicit INIFile();
-
- bool loadFile(QByteArray file);
- bool loadFile(QString fileName);
- bool saveFile(QString fileName);
-
- QVariant get(QString key, QVariant def) const;
- void set(QString key, QVariant val);
- static QString unescape(QString orig);
- static QString escape(QString orig);
-};
diff --git a/libraries/logic/settings/INISettingsObject.cpp b/libraries/logic/settings/INISettingsObject.cpp
deleted file mode 100644
index 5ccc7446..00000000
--- a/libraries/logic/settings/INISettingsObject.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Copyright 2013-2015 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 "INISettingsObject.h"
-#include "Setting.h"
-
-INISettingsObject::INISettingsObject(const QString &path, QObject *parent)
- : SettingsObject(parent)
-{
- m_filePath = path;
- m_ini.loadFile(path);
-}
-
-void INISettingsObject::setFilePath(const QString &filePath)
-{
- m_filePath = filePath;
-}
-
-bool INISettingsObject::reload()
-{
- return m_ini.loadFile(m_filePath) && SettingsObject::reload();
-}
-
-void INISettingsObject::suspendSave()
-{
- m_suspendSave = true;
-}
-
-void INISettingsObject::resumeSave()
-{
- m_suspendSave = false;
- if(m_doSave)
- {
- m_ini.saveFile(m_filePath);
- }
-}
-
-void INISettingsObject::changeSetting(const Setting &setting, QVariant value)
-{
- if (contains(setting.id()))
- {
- // valid value -> set the main config, remove all the sysnonyms
- if (value.isValid())
- {
- auto list = setting.configKeys();
- m_ini.set(list.takeFirst(), value);
- for(auto iter: list)
- m_ini.remove(iter);
- }
- // invalid -> remove all (just like resetSetting)
- else
- {
- for(auto iter: setting.configKeys())
- m_ini.remove(iter);
- }
- doSave();
- }
-}
-
-void INISettingsObject::doSave()
-{
- if(m_suspendSave)
- {
- m_doSave = true;
- }
- else
- {
- m_ini.saveFile(m_filePath);
- }
-}
-
-void INISettingsObject::resetSetting(const Setting &setting)
-{
- // if we have the setting, remove all the synonyms. ALL OF THEM
- if (contains(setting.id()))
- {
- for(auto iter: setting.configKeys())
- m_ini.remove(iter);
- doSave();
- }
-}
-
-QVariant INISettingsObject::retrieveValue(const Setting &setting)
-{
- // if we have the setting, return value of the first matching synonym
- if (contains(setting.id()))
- {
- for(auto iter: setting.configKeys())
- {
- if(m_ini.contains(iter))
- return m_ini[iter];
- }
- }
- return QVariant();
-}
diff --git a/libraries/logic/settings/INISettingsObject.h b/libraries/logic/settings/INISettingsObject.h
deleted file mode 100644
index 4afa2a2c..00000000
--- a/libraries/logic/settings/INISettingsObject.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-
-#include "settings/INIFile.h"
-
-#include "settings/SettingsObject.h"
-
-#include "multimc_logic_export.h"
-
-/*!
- * \brief A settings object that stores its settings in an INIFile.
- */
-class MULTIMC_LOGIC_EXPORT INISettingsObject : public SettingsObject
-{
- Q_OBJECT
-public:
- explicit INISettingsObject(const QString &path, QObject *parent = 0);
-
- /*!
- * \brief Gets the path to the INI file.
- * \return The path to the INI file.
- */
- virtual QString filePath() const
- {
- return m_filePath;
- }
-
- /*!
- * \brief Sets the path to the INI file and reloads it.
- * \param filePath The INI file's new path.
- */
- virtual void setFilePath(const QString &filePath);
-
- bool reload() override;
-
- void suspendSave() override;
- void resumeSave() override;
-
-protected slots:
- virtual void changeSetting(const Setting &setting, QVariant value) override;
- virtual void resetSetting(const Setting &setting) override;
-
-protected:
- virtual QVariant retrieveValue(const Setting &setting) override;
- void doSave();
-
-protected:
- INIFile m_ini;
- QString m_filePath;
-};
diff --git a/libraries/logic/settings/OverrideSetting.cpp b/libraries/logic/settings/OverrideSetting.cpp
deleted file mode 100644
index 25162dff..00000000
--- a/libraries/logic/settings/OverrideSetting.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright 2013-2015 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 "OverrideSetting.h"
-
-OverrideSetting::OverrideSetting(std::shared_ptr<Setting> other, std::shared_ptr<Setting> gate)
- : Setting(other->configKeys(), QVariant())
-{
- Q_ASSERT(other);
- Q_ASSERT(gate);
- m_other = other;
- m_gate = gate;
-}
-
-bool OverrideSetting::isOverriding() const
-{
- return m_gate->get().toBool();
-}
-
-QVariant OverrideSetting::defValue() const
-{
- return m_other->get();
-}
-
-QVariant OverrideSetting::get() const
-{
- if(isOverriding())
- {
- return Setting::get();
- }
- return m_other->get();
-}
-
-void OverrideSetting::reset()
-{
- Setting::reset();
-}
-
-void OverrideSetting::set(QVariant value)
-{
- Setting::set(value);
-}
diff --git a/libraries/logic/settings/OverrideSetting.h b/libraries/logic/settings/OverrideSetting.h
deleted file mode 100644
index 68595cde..00000000
--- a/libraries/logic/settings/OverrideSetting.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <memory>
-
-#include "Setting.h"
-
-/*!
- * \brief A setting that 'overrides another.'
- * This means that the setting's default value will be the value of another setting.
- * The other setting can be (and usually is) a part of a different SettingsObject
- * than this one.
- */
-class OverrideSetting : public Setting
-{
- Q_OBJECT
-public:
- explicit OverrideSetting(std::shared_ptr<Setting> overriden, std::shared_ptr<Setting> gate);
-
- virtual QVariant defValue() const;
- virtual QVariant get() const;
- virtual void set (QVariant value);
- virtual void reset();
-
-private:
- bool isOverriding() const;
-
-protected:
- std::shared_ptr<Setting> m_other;
- std::shared_ptr<Setting> m_gate;
-};
diff --git a/libraries/logic/settings/PassthroughSetting.cpp b/libraries/logic/settings/PassthroughSetting.cpp
deleted file mode 100644
index 45a560de..00000000
--- a/libraries/logic/settings/PassthroughSetting.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright 2013-2015 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 "PassthroughSetting.h"
-
-PassthroughSetting::PassthroughSetting(std::shared_ptr<Setting> other, std::shared_ptr<Setting> gate)
- : Setting(other->configKeys(), QVariant())
-{
- Q_ASSERT(other);
- Q_ASSERT(gate);
- m_other = other;
- m_gate = gate;
-}
-
-bool PassthroughSetting::isOverriding() const
-{
- return m_gate->get().toBool();
-}
-
-QVariant PassthroughSetting::defValue() const
-{
- if(isOverriding())
- {
- return m_other->get();
- }
- return m_other->defValue();
-}
-
-QVariant PassthroughSetting::get() const
-{
- if(isOverriding())
- {
- return Setting::get();
- }
- return m_other->get();
-}
-
-void PassthroughSetting::reset()
-{
- if(isOverriding())
- {
- Setting::reset();
- }
- m_other->reset();
-}
-
-void PassthroughSetting::set(QVariant value)
-{
- if(isOverriding())
- {
- Setting::set(value);
- }
- m_other->set(value);
-}
diff --git a/libraries/logic/settings/PassthroughSetting.h b/libraries/logic/settings/PassthroughSetting.h
deleted file mode 100644
index c4dc646c..00000000
--- a/libraries/logic/settings/PassthroughSetting.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <memory>
-
-#include "Setting.h"
-
-/*!
- * \brief A setting that 'overrides another.' based on the value of a 'gate' setting
- * If 'gate' evaluates to true, the override stores and returns data
- * If 'gate' evaluates to false, the original does,
- */
-class PassthroughSetting : public Setting
-{
- Q_OBJECT
-public:
- explicit PassthroughSetting(std::shared_ptr<Setting> overriden, std::shared_ptr<Setting> gate);
-
- virtual QVariant defValue() const;
- virtual QVariant get() const;
- virtual void set (QVariant value);
- virtual void reset();
-
-private:
- bool isOverriding() const;
-
-protected:
- std::shared_ptr<Setting> m_other;
- std::shared_ptr<Setting> m_gate;
-};
diff --git a/libraries/logic/settings/Setting.cpp b/libraries/logic/settings/Setting.cpp
deleted file mode 100644
index b17101a2..00000000
--- a/libraries/logic/settings/Setting.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright 2013-2015 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 "Setting.h"
-#include "settings/SettingsObject.h"
-
-Setting::Setting(QStringList synonyms, QVariant defVal)
- : QObject(), m_synonyms(synonyms), m_defVal(defVal)
-{
-}
-
-QVariant Setting::get() const
-{
- SettingsObject *sbase = m_storage;
- if (!sbase)
- {
- return defValue();
- }
- else
- {
- QVariant test = sbase->retrieveValue(*this);
- if (!test.isValid())
- return defValue();
- return test;
- }
-}
-
-QVariant Setting::defValue() const
-{
- return m_defVal;
-}
-
-void Setting::set(QVariant value)
-{
- emit SettingChanged(*this, value);
-}
-
-void Setting::reset()
-{
- emit settingReset(*this);
-}
diff --git a/libraries/logic/settings/Setting.h b/libraries/logic/settings/Setting.h
deleted file mode 100644
index 6d53ac6d..00000000
--- a/libraries/logic/settings/Setting.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QVariant>
-#include <QStringList>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class SettingsObject;
-
-/*!
- *
- */
-class MULTIMC_LOGIC_EXPORT Setting : public QObject
-{
- Q_OBJECT
-public:
- /**
- * Construct a Setting
- *
- * Synonyms are all the possible names used in the settings object, in order of preference.
- * First synonym is the ID, which identifies the setting in MultiMC.
- *
- * defVal is the default value that will be returned when the settings object
- * doesn't have any value for this setting.
- */
- explicit Setting(QStringList synonyms, QVariant defVal = QVariant());
-
- /*!
- * \brief Gets this setting's ID.
- * This is used to refer to the setting within the application.
- * \warning Changing the ID while the setting is registered with a SettingsObject results in
- * undefined behavior.
- * \return The ID of the setting.
- */
- virtual QString id() const
- {
- return m_synonyms.first();
- }
-
- /*!
- * \brief Gets this setting's config file key.
- * This is used to store the setting's value in the config file. It is usually
- * the same as the setting's ID, but it can be different.
- * \return The setting's config file key.
- */
- virtual QStringList configKeys() const
- {
- return m_synonyms;
- }
-
- /*!
- * \brief Gets this setting's value as a QVariant.
- * This is done by calling the SettingsObject's retrieveValue() function.
- * If this Setting doesn't have a SettingsObject, this returns an invalid QVariant.
- * \return QVariant containing this setting's value.
- * \sa value()
- */
- virtual QVariant get() const;
-
- /*!
- * \brief Gets this setting's default value.
- * \return The default value of this setting.
- */
- virtual QVariant defValue() const;
-
-signals:
- /*!
- * \brief Signal emitted when this Setting object's value changes.
- * \param setting A reference to the Setting that changed.
- * \param value This Setting object's new value.
- */
- void SettingChanged(const Setting &setting, QVariant value);
-
- /*!
- * \brief Signal emitted when this Setting object's value resets to default.
- * \param setting A reference to the Setting that changed.
- */
- void settingReset(const Setting &setting);
-
-public
-slots:
- /*!
- * \brief Changes the setting's value.
- * This is done by emitting the SettingChanged() signal which will then be
- * handled by the SettingsObject object and cause the setting to change.
- * \param value The new value.
- */
- virtual void set(QVariant value);
-
- /*!
- * \brief Reset the setting to default
- * This is done by emitting the settingReset() signal which will then be
- * handled by the SettingsObject object and cause the setting to change.
- */
- virtual void reset();
-
-protected:
- friend class SettingsObject;
- SettingsObject * m_storage;
- QStringList m_synonyms;
- QVariant m_defVal;
-};
diff --git a/libraries/logic/settings/SettingsObject.cpp b/libraries/logic/settings/SettingsObject.cpp
deleted file mode 100644
index f2ffdf9b..00000000
--- a/libraries/logic/settings/SettingsObject.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright 2013-2015 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 "settings/SettingsObject.h"
-#include "settings/Setting.h"
-#include "settings/OverrideSetting.h"
-#include "PassthroughSetting.h"
-#include <QDebug>
-
-#include <QVariant>
-
-SettingsObject::SettingsObject(QObject *parent) : QObject(parent)
-{
-}
-
-SettingsObject::~SettingsObject()
-{
- m_settings.clear();
-}
-
-std::shared_ptr<Setting> SettingsObject::registerOverride(std::shared_ptr<Setting> original,
- std::shared_ptr<Setting> gate)
-{
- if (contains(original->id()))
- {
- qCritical() << QString("Failed to register setting %1. ID already exists.")
- .arg(original->id());
- return nullptr; // Fail
- }
- auto override = std::make_shared<OverrideSetting>(original, gate);
- override->m_storage = this;
- connectSignals(*override);
- m_settings.insert(override->id(), override);
- return override;
-}
-
-std::shared_ptr<Setting> SettingsObject::registerPassthrough(std::shared_ptr<Setting> original,
- std::shared_ptr<Setting> gate)
-{
- if (contains(original->id()))
- {
- qCritical() << QString("Failed to register setting %1. ID already exists.")
- .arg(original->id());
- return nullptr; // Fail
- }
- auto passthrough = std::make_shared<PassthroughSetting>(original, gate);
- passthrough->m_storage = this;
- connectSignals(*passthrough);
- m_settings.insert(passthrough->id(), passthrough);
- return passthrough;
-}
-
-std::shared_ptr<Setting> SettingsObject::registerSetting(QStringList synonyms, QVariant defVal)
-{
- if (synonyms.empty())
- return nullptr;
- if (contains(synonyms.first()))
- {
- qCritical() << QString("Failed to register setting %1. ID already exists.")
- .arg(synonyms.first());
- return nullptr; // Fail
- }
- auto setting = std::make_shared<Setting>(synonyms, defVal);
- setting->m_storage = this;
- connectSignals(*setting);
- m_settings.insert(setting->id(), setting);
- return setting;
-}
-
-std::shared_ptr<Setting> SettingsObject::getSetting(const QString &id) const
-{
- // Make sure there is a setting with the given ID.
- if (!m_settings.contains(id))
- return NULL;
-
- return m_settings[id];
-}
-
-QVariant SettingsObject::get(const QString &id) const
-{
- auto setting = getSetting(id);
- return (setting ? setting->get() : QVariant());
-}
-
-bool SettingsObject::set(const QString &id, QVariant value)
-{
- auto setting = getSetting(id);
- if (!setting)
- {
- qCritical() << QString("Error changing setting %1. Setting doesn't exist.").arg(id);
- return false;
- }
- else
- {
- setting->set(value);
- return true;
- }
-}
-
-void SettingsObject::reset(const QString &id) const
-{
- auto setting = getSetting(id);
- if (setting)
- setting->reset();
-}
-
-bool SettingsObject::contains(const QString &id)
-{
- return m_settings.contains(id);
-}
-
-bool SettingsObject::reload()
-{
- for (auto setting : m_settings.values())
- {
- setting->set(setting->get());
- }
- return true;
-}
-
-void SettingsObject::connectSignals(const Setting &setting)
-{
- connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)),
- SLOT(changeSetting(const Setting &, QVariant)));
- connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)),
- SIGNAL(SettingChanged(const Setting &, QVariant)));
-
- connect(&setting, SIGNAL(settingReset(Setting)), SLOT(resetSetting(const Setting &)));
- connect(&setting, SIGNAL(settingReset(Setting)), SIGNAL(settingReset(const Setting &)));
-}
diff --git a/libraries/logic/settings/SettingsObject.h b/libraries/logic/settings/SettingsObject.h
deleted file mode 100644
index 82193903..00000000
--- a/libraries/logic/settings/SettingsObject.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QMap>
-#include <QStringList>
-#include <QVariant>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class Setting;
-class SettingsObject;
-
-typedef std::shared_ptr<SettingsObject> SettingsObjectPtr;
-
-/*!
- * \brief The SettingsObject handles communicating settings between the application and a
- *settings file.
- * The class keeps a list of Setting objects. Each Setting object represents one
- * of the application's settings. These Setting objects are registered with
- * a SettingsObject and can be managed similarly to the way a list works.
- *
- * \author Andrew Okin
- * \date 2/22/2013
- *
- * \sa Setting
- */
-class MULTIMC_LOGIC_EXPORT SettingsObject : public QObject
-{
- Q_OBJECT
-public:
- class Lock
- {
- public:
- Lock(SettingsObjectPtr locked)
- :m_locked(locked)
- {
- m_locked->suspendSave();
- }
- ~Lock()
- {
- m_locked->resumeSave();
- }
- private:
- SettingsObjectPtr m_locked;
- };
-public:
- explicit SettingsObject(QObject *parent = 0);
- virtual ~SettingsObject();
- /*!
- * Registers an override setting for the given original setting in this settings object
- * gate decides if the passthrough (true) or the original (false) is used for value
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerOverride(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);
-
- /*!
- * Registers a passthorugh setting for the given original setting in this settings object
- * gate decides if the passthrough (true) or the original (false) is used for value
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerPassthrough(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);
-
- /*!
- * Registers the given setting with this SettingsObject and connects the necessary signals.
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerSetting(QStringList synonyms,
- QVariant defVal = QVariant());
-
- /*!
- * Registers the given setting with this SettingsObject and connects the necessary signals.
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerSetting(QString id, QVariant defVal = QVariant())
- {
- return registerSetting(QStringList(id), defVal);
- }
-
- /*!
- * \brief Gets the setting with the given ID.
- * \param id The ID of the setting to get.
- * \return A pointer to the setting with the given ID.
- * Returns null if there is no setting with the given ID.
- * \sa operator []()
- */
- std::shared_ptr<Setting> getSetting(const QString &id) const;
-
- /*!
- * \brief Gets the value of the setting with the given ID.
- * \param id The ID of the setting to get.
- * \return The setting's value as a QVariant.
- * If no setting with the given ID exists, returns an invalid QVariant.
- */
- QVariant get(const QString &id) const;
-
- /*!
- * \brief Sets the value of the setting with the given ID.
- * If no setting with the given ID exists, returns false
- * \param id The ID of the setting to change.
- * \param value The new value of the setting.
- * \return True if successful, false if it failed.
- */
- bool set(const QString &id, QVariant value);
-
- /*!
- * \brief Reverts the setting with the given ID to default.
- * \param id The ID of the setting to reset.
- */
- void reset(const QString &id) const;
-
- /*!
- * \brief Checks if this SettingsObject contains a setting with the given ID.
- * \param id The ID to check for.
- * \return True if the SettingsObject has a setting with the given ID.
- */
- bool contains(const QString &id);
-
- /*!
- * \brief Reloads the settings and emit signals for changed settings
- * \return True if reloading was successful
- */
- virtual bool reload();
-
- virtual void suspendSave() = 0;
- virtual void resumeSave() = 0;
-signals:
- /*!
- * \brief Signal emitted when one of this SettingsObject object's settings changes.
- * This is usually just connected directly to each Setting object's
- * SettingChanged() signals.
- * \param setting A reference to the Setting object that changed.
- * \param value The Setting object's new value.
- */
- void SettingChanged(const Setting &setting, QVariant value);
-
- /*!
- * \brief Signal emitted when one of this SettingsObject object's settings resets.
- * This is usually just connected directly to each Setting object's
- * settingReset() signals.
- * \param setting A reference to the Setting object that changed.
- */
- void settingReset(const Setting &setting);
-
-protected
-slots:
- /*!
- * \brief Changes a setting.
- * This slot is usually connected to each Setting object's
- * SettingChanged() signal. The signal is emitted, causing this slot
- * to update the setting's value in the config file.
- * \param setting A reference to the Setting object that changed.
- * \param value The setting's new value.
- */
- virtual void changeSetting(const Setting &setting, QVariant value) = 0;
-
- /*!
- * \brief Resets a setting.
- * This slot is usually connected to each Setting object's
- * settingReset() signal. The signal is emitted, causing this slot
- * to update the setting's value in the config file.
- * \param setting A reference to the Setting object that changed.
- */
- virtual void resetSetting(const Setting &setting) = 0;
-
-protected:
- /*!
- * \brief Connects the necessary signals to the given Setting.
- * \param setting The setting to connect.
- */
- void connectSignals(const Setting &setting);
-
- /*!
- * \brief Function used by Setting objects to get their values from the SettingsObject.
- * \param setting The
- * \return
- */
- virtual QVariant retrieveValue(const Setting &setting) = 0;
-
- friend class Setting;
-
-private:
- QMap<QString, std::shared_ptr<Setting>> m_settings;
-protected:
- bool m_suspendSave = false;
- bool m_doSave = false;
-};
diff --git a/libraries/logic/status/StatusChecker.cpp b/libraries/logic/status/StatusChecker.cpp
deleted file mode 100644
index 13cac037..00000000
--- a/libraries/logic/status/StatusChecker.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Copyright 2013-2015 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 "StatusChecker.h"
-
-#include <net/URLConstants.h>
-
-#include <QByteArray>
-
-#include <QDebug>
-
-StatusChecker::StatusChecker()
-{
-
-}
-
-void StatusChecker::timerEvent(QTimerEvent *e)
-{
- QObject::timerEvent(e);
- reloadStatus();
-}
-
-void StatusChecker::reloadStatus()
-{
- if (isLoadingStatus())
- {
- // qDebug() << "Ignored request to reload status. Currently reloading already.";
- return;
- }
-
- // qDebug() << "Reloading status.";
-
- NetJob* job = new NetJob("Status JSON");
- job->addNetAction(ByteArrayDownload::make(URLConstants::MOJANG_STATUS_URL));
- QObject::connect(job, &NetJob::succeeded, this, &StatusChecker::statusDownloadFinished);
- QObject::connect(job, &NetJob::failed, this, &StatusChecker::statusDownloadFailed);
- m_statusNetJob.reset(job);
- emit statusLoading(true);
- job->start();
-}
-
-void StatusChecker::statusDownloadFinished()
-{
- qDebug() << "Finished loading status JSON.";
- m_statusEntries.clear();
- QByteArray data;
- {
- ByteArrayDownloadPtr dl = std::dynamic_pointer_cast<ByteArrayDownload>(m_statusNetJob->first());
- data = dl->m_data;
- m_statusNetJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- fail("Error parsing status JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isArray())
- {
- fail("Error parsing status JSON: JSON root is not an array");
- return;
- }
-
- QJsonArray root = jsonDoc.array();
-
- for(auto status = root.begin(); status != root.end(); ++status)
- {
- QVariantMap map = (*status).toObject().toVariantMap();
-
- for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
- {
- QString key = iter.key();
- QVariant value = iter.value();
-
- if(value.type() == QVariant::Type::String)
- {
- m_statusEntries.insert(key, value.toString());
- //qDebug() << "Status JSON object: " << key << m_statusEntries[key];
- }
- else
- {
- fail("Malformed status JSON: expected status type to be a string.");
- return;
- }
- }
- }
-
- succeed();
-}
-
-void StatusChecker::statusDownloadFailed(QString reason)
-{
- fail(tr("Failed to load status JSON:\n%1").arg(reason));
-}
-
-
-QMap<QString, QString> StatusChecker::getStatusEntries() const
-{
- return m_statusEntries;
-}
-
-bool StatusChecker::isLoadingStatus() const
-{
- return m_statusNetJob.get() != nullptr;
-}
-
-QString StatusChecker::getLastLoadErrorMsg() const
-{
- return m_lastLoadError;
-}
-
-void StatusChecker::succeed()
-{
- if(m_prevEntries != m_statusEntries)
- {
- emit statusChanged(m_statusEntries);
- m_prevEntries = m_statusEntries;
- }
- m_lastLoadError = "";
- qDebug() << "Status loading succeeded.";
- m_statusNetJob.reset();
- emit statusLoading(false);
-}
-
-void StatusChecker::fail(const QString& errorMsg)
-{
- if(m_prevEntries != m_statusEntries)
- {
- emit statusChanged(m_statusEntries);
- m_prevEntries = m_statusEntries;
- }
- m_lastLoadError = errorMsg;
- qDebug() << "Failed to load status:" << errorMsg;
- m_statusNetJob.reset();
- emit statusLoading(false);
-}
-
diff --git a/libraries/logic/status/StatusChecker.h b/libraries/logic/status/StatusChecker.h
deleted file mode 100644
index c1a54dba..00000000
--- a/libraries/logic/status/StatusChecker.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QString>
-#include <QList>
-
-#include <net/NetJob.h>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT StatusChecker : public QObject
-{
- Q_OBJECT
-public:
- StatusChecker();
-
- QString getLastLoadErrorMsg() const;
-
- bool isLoadingStatus() const;
-
- QMap<QString, QString> getStatusEntries() const;
-
- void Q_SLOT reloadStatus();
-
-protected:
- virtual void timerEvent(QTimerEvent *);
-
-signals:
- void statusLoading(bool loading);
- void statusChanged(QMap<QString, QString> newStatus);
-
-protected slots:
- void statusDownloadFinished();
- void statusDownloadFailed(QString reason);
-
-protected:
- QMap<QString, QString> m_prevEntries;
- QMap<QString, QString> m_statusEntries;
- NetJobPtr m_statusNetJob;
- QString m_lastLoadError;
-
- void Q_SLOT succeed();
- void Q_SLOT fail(const QString& errorMsg);
-};
-
diff --git a/libraries/logic/tasks/SequentialTask.cpp b/libraries/logic/tasks/SequentialTask.cpp
deleted file mode 100644
index ac0e7820..00000000
--- a/libraries/logic/tasks/SequentialTask.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "SequentialTask.h"
-
-SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(-1)
-{
-}
-
-void SequentialTask::addTask(std::shared_ptr<Task> task)
-{
- m_queue.append(task);
-}
-
-void SequentialTask::executeTask()
-{
- m_currentIndex = -1;
- startNext();
-}
-
-void SequentialTask::startNext()
-{
- if (m_currentIndex != -1)
- {
- std::shared_ptr<Task> previous = m_queue[m_currentIndex];
- disconnect(previous.get(), 0, this, 0);
- }
- m_currentIndex++;
- if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
- {
- emitSucceeded();
- return;
- }
- std::shared_ptr<Task> next = m_queue[m_currentIndex];
- connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString)));
- connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
- connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
- connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
- next->start();
-}
-
-void SequentialTask::subTaskFailed(const QString &msg)
-{
- emitFailed(msg);
-}
-void SequentialTask::subTaskStatus(const QString &msg)
-{
- setStatus(msg);
-}
-void SequentialTask::subTaskProgress(qint64 current, qint64 total)
-{
- if(total == 0)
- {
- setProgress(0, 100);
- return;
- }
- setProgress(current, total);
-}
diff --git a/libraries/logic/tasks/SequentialTask.h b/libraries/logic/tasks/SequentialTask.h
deleted file mode 100644
index 69031095..00000000
--- a/libraries/logic/tasks/SequentialTask.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include "Task.h"
-
-#include <QQueue>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT SequentialTask : public Task
-{
- Q_OBJECT
-public:
- explicit SequentialTask(QObject *parent = 0);
-
- void addTask(std::shared_ptr<Task> task);
-
-protected:
- void executeTask();
-
-private
-slots:
- void startNext();
- void subTaskFailed(const QString &msg);
- void subTaskStatus(const QString &msg);
- void subTaskProgress(qint64 current, qint64 total);
-
-private:
- QQueue<std::shared_ptr<Task> > m_queue;
- int m_currentIndex;
-};
diff --git a/libraries/logic/tasks/Task.cpp b/libraries/logic/tasks/Task.cpp
deleted file mode 100644
index 3c4e3188..00000000
--- a/libraries/logic/tasks/Task.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright 2013-2015 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 "Task.h"
-
-#include <QDebug>
-
-Task::Task(QObject *parent) : QObject(parent)
-{
-}
-
-void Task::setStatus(const QString &new_status)
-{
- if(m_status != new_status)
- {
- m_status = new_status;
- emit status(m_status);
- }
-}
-
-void Task::setProgress(qint64 current, qint64 total)
-{
- m_progress = current;
- m_progressTotal = total;
- emit progress(m_progress, m_progressTotal);
-}
-
-void Task::start()
-{
- m_running = true;
- emit started();
- executeTask();
-}
-
-void Task::emitFailed(QString reason)
-{
- m_running = false;
- m_finished = true;
- m_succeeded = false;
- m_failReason = reason;
- qCritical() << "Task failed: " << reason;
- emit failed(reason);
- emit finished();
-}
-
-void Task::emitSucceeded()
-{
- if (!m_running) { return; } // Don't succeed twice.
- m_running = false;
- m_finished = true;
- m_succeeded = true;
- qDebug() << "Task succeeded";
- emit succeeded();
- emit finished();
-}
-
-bool Task::isRunning() const
-{
- return m_running;
-}
-
-bool Task::isFinished() const
-{
- return m_finished;
-}
-
-bool Task::successful() const
-{
- return m_succeeded;
-}
-
-QString Task::failReason() const
-{
- return m_failReason;
-}
-
diff --git a/libraries/logic/tasks/Task.h b/libraries/logic/tasks/Task.h
deleted file mode 100644
index 2b0ccbcd..00000000
--- a/libraries/logic/tasks/Task.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <QString>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT Task : public QObject
-{
- Q_OBJECT
-public:
- explicit Task(QObject *parent = 0);
- virtual ~Task() {};
-
- virtual bool isRunning() const;
-
- virtual bool isFinished() const;
-
- /*!
- * True if this task was successful.
- * If the task failed or is still running, returns false.
- */
- virtual bool successful() const;
-
- /*!
- * Returns the string that was passed to emitFailed as the error message when the task failed.
- * If the task hasn't failed, returns an empty string.
- */
- virtual QString failReason() const;
-
- virtual bool canAbort() const { return false; }
-
- QString getStatus()
- {
- return m_status;
- }
-
- qint64 getProgress()
- {
- return m_progress;
- }
-
- qint64 getTotalProgress()
- {
- return m_progressTotal;
- }
-
-signals:
- void started();
- void progress(qint64 current, qint64 total);
- void finished();
- void succeeded();
- void failed(QString reason);
- void status(QString status);
-
-public
-slots:
- virtual void start();
- virtual bool abort() { return false; };
-
-protected:
- virtual void executeTask() = 0;
-
-protected slots:
- virtual void emitSucceeded();
- virtual void emitFailed(QString reason);
-
-public slots:
- void setStatus(const QString &status);
- void setProgress(qint64 current, qint64 total);
-
-protected:
- bool m_running = false;
- bool m_finished = false;
- bool m_succeeded = false;
- QString m_failReason = "";
- QString m_status;
- int m_progress = 0;
- int m_progressTotal = 100;
-};
-
diff --git a/libraries/logic/tasks/ThreadTask.cpp b/libraries/logic/tasks/ThreadTask.cpp
deleted file mode 100644
index ddd1dee5..00000000
--- a/libraries/logic/tasks/ThreadTask.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "ThreadTask.h"
-#include <QtConcurrentRun>
-ThreadTask::ThreadTask(Task * internal, QObject *parent) : Task(parent), m_internal(internal)
-{
-}
-
-void ThreadTask::start()
-{
- connect(m_internal, SIGNAL(failed(QString)), SLOT(iternal_failed(QString)));
- connect(m_internal, SIGNAL(progress(qint64,qint64)), SLOT(iternal_progress(qint64,qint64)));
- connect(m_internal, SIGNAL(started()), SLOT(iternal_started()));
- connect(m_internal, SIGNAL(status(QString)), SLOT(iternal_status(QString)));
- connect(m_internal, SIGNAL(succeeded()), SLOT(iternal_succeeded()));
- m_running = true;
- QtConcurrent::run(m_internal, &Task::start);
-}
-
-void ThreadTask::iternal_failed(QString reason)
-{
- emitFailed(reason);
-}
-
-void ThreadTask::iternal_progress(qint64 current, qint64 total)
-{
- progress(current, total);
-}
-
-void ThreadTask::iternal_started()
-{
- emit started();
-}
-
-void ThreadTask::iternal_status(QString status)
-{
- setStatus(status);
-}
-
-void ThreadTask::iternal_succeeded()
-{
- emitSucceeded();
-}
diff --git a/libraries/logic/tasks/ThreadTask.h b/libraries/logic/tasks/ThreadTask.h
deleted file mode 100644
index 718dbc91..00000000
--- a/libraries/logic/tasks/ThreadTask.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include "Task.h"
-
-class ThreadTask : public Task
-{
- Q_OBJECT
-public:
- explicit ThreadTask(Task * internal, QObject * parent = nullptr);
-
-protected:
- void executeTask() {};
-
-public slots:
- virtual void start();
-
-private slots:
- void iternal_started();
- void iternal_progress(qint64 current, qint64 total);
- void iternal_succeeded();
- void iternal_failed(QString reason);
- void iternal_status(QString status);
-private:
- Task * m_internal;
-}; \ No newline at end of file
diff --git a/libraries/logic/tools/BaseExternalTool.cpp b/libraries/logic/tools/BaseExternalTool.cpp
deleted file mode 100644
index 2b97c3c9..00000000
--- a/libraries/logic/tools/BaseExternalTool.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "BaseExternalTool.h"
-
-#include <QProcess>
-#include <QDir>
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#endif
-
-#include "BaseInstance.h"
-
-BaseExternalTool::BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : QObject(parent), m_instance(instance), globalSettings(settings)
-{
-}
-
-BaseExternalTool::~BaseExternalTool()
-{
-}
-
-BaseDetachedTool::BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseExternalTool(settings, instance, parent)
-{
-
-}
-
-void BaseDetachedTool::run()
-{
- runImpl();
-}
-
-
-BaseExternalToolFactory::~BaseExternalToolFactory()
-{
-}
-
-BaseDetachedTool *BaseDetachedToolFactory::createDetachedTool(InstancePtr instance,
- QObject *parent)
-{
- return qobject_cast<BaseDetachedTool *>(createTool(instance, parent));
-}
diff --git a/libraries/logic/tools/BaseExternalTool.h b/libraries/logic/tools/BaseExternalTool.h
deleted file mode 100644
index fe1b5dc6..00000000
--- a/libraries/logic/tools/BaseExternalTool.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <QObject>
-#include <BaseInstance.h>
-
-#include "multimc_logic_export.h"
-
-class BaseInstance;
-class SettingsObject;
-class QProcess;
-
-class MULTIMC_LOGIC_EXPORT BaseExternalTool : public QObject
-{
- Q_OBJECT
-public:
- explicit BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
- virtual ~BaseExternalTool();
-
-protected:
- InstancePtr m_instance;
- SettingsObjectPtr globalSettings;
-};
-
-class MULTIMC_LOGIC_EXPORT BaseDetachedTool : public BaseExternalTool
-{
- Q_OBJECT
-public:
- explicit BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
-
-public
-slots:
- void run();
-
-protected:
- virtual void runImpl() = 0;
-};
-
-class MULTIMC_LOGIC_EXPORT BaseExternalToolFactory
-{
-public:
- virtual ~BaseExternalToolFactory();
-
- virtual QString name() const = 0;
-
- virtual void registerSettings(SettingsObjectPtr settings) = 0;
-
- virtual BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) = 0;
-
- virtual bool check(QString *error) = 0;
- virtual bool check(const QString &path, QString *error) = 0;
-
-protected:
- SettingsObjectPtr globalSettings;
-};
-
-class MULTIMC_LOGIC_EXPORT BaseDetachedToolFactory : public BaseExternalToolFactory
-{
-public:
- virtual BaseDetachedTool *createDetachedTool(InstancePtr instance, QObject *parent = 0);
-};
diff --git a/libraries/logic/tools/BaseProfiler.cpp b/libraries/logic/tools/BaseProfiler.cpp
deleted file mode 100644
index 5ff0fa44..00000000
--- a/libraries/logic/tools/BaseProfiler.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "BaseProfiler.h"
-
-#include <QProcess>
-
-BaseProfiler::BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseExternalTool(settings, instance, parent)
-{
-}
-
-void BaseProfiler::beginProfiling(std::shared_ptr<LaunchTask> process)
-{
- beginProfilingImpl(process);
-}
-
-void BaseProfiler::abortProfiling()
-{
- abortProfilingImpl();
-}
-
-void BaseProfiler::abortProfilingImpl()
-{
- if (!m_profilerProcess)
- {
- return;
- }
- m_profilerProcess->terminate();
- m_profilerProcess->deleteLater();
- m_profilerProcess = 0;
- emit abortLaunch(tr("Profiler aborted"));
-}
-
-BaseProfiler *BaseProfilerFactory::createProfiler(InstancePtr instance, QObject *parent)
-{
- return qobject_cast<BaseProfiler *>(createTool(instance, parent));
-}
diff --git a/libraries/logic/tools/BaseProfiler.h b/libraries/logic/tools/BaseProfiler.h
deleted file mode 100644
index 3340b7e4..00000000
--- a/libraries/logic/tools/BaseProfiler.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "BaseExternalTool.h"
-
-#include "multimc_logic_export.h"
-
-class BaseInstance;
-class SettingsObject;
-class LaunchTask;
-class QProcess;
-
-class MULTIMC_LOGIC_EXPORT BaseProfiler : public BaseExternalTool
-{
- Q_OBJECT
-public:
- explicit BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
-
-public
-slots:
- void beginProfiling(std::shared_ptr<LaunchTask> process);
- void abortProfiling();
-
-protected:
- QProcess *m_profilerProcess;
-
- virtual void beginProfilingImpl(std::shared_ptr<LaunchTask> process) = 0;
- virtual void abortProfilingImpl();
-
-signals:
- void readyToLaunch(const QString &message);
- void abortLaunch(const QString &message);
-};
-
-class MULTIMC_LOGIC_EXPORT BaseProfilerFactory : public BaseExternalToolFactory
-{
-public:
- virtual BaseProfiler *createProfiler(InstancePtr instance, QObject *parent = 0);
-};
diff --git a/libraries/logic/tools/JProfiler.cpp b/libraries/logic/tools/JProfiler.cpp
deleted file mode 100644
index a0e3c895..00000000
--- a/libraries/logic/tools/JProfiler.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "JProfiler.h"
-
-#include <QDir>
-
-#include "settings/SettingsObject.h"
-#include "launch/LaunchTask.h"
-#include "BaseInstance.h"
-
-class JProfiler : public BaseProfiler
-{
- Q_OBJECT
-public:
- JProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
-
-private slots:
- void profilerStarted();
- void profilerFinished(int exit, QProcess::ExitStatus status);
-
-protected:
- void beginProfilingImpl(std::shared_ptr<LaunchTask> process);
-
-private:
- int listeningPort = 0;
-};
-
-JProfiler::JProfiler(SettingsObjectPtr settings, InstancePtr instance,
- QObject *parent)
- : BaseProfiler(settings, instance, parent)
-{
-}
-
-void JProfiler::profilerStarted()
-{
- emit readyToLaunch(tr("Listening on port: %1").arg(listeningPort));
-}
-
-void JProfiler::profilerFinished(int exit, QProcess::ExitStatus status)
-{
- if (status == QProcess::CrashExit)
- {
- emit abortLaunch(tr("Profiler aborted"));
- }
- if (m_profilerProcess)
- {
- m_profilerProcess->deleteLater();
- m_profilerProcess = 0;
- }
-}
-
-void JProfiler::beginProfilingImpl(std::shared_ptr<LaunchTask> process)
-{
- listeningPort = globalSettings->get("JProfilerPort").toInt();
- QProcess *profiler = new QProcess(this);
- QStringList profilerArgs =
- {
- "-d", QString::number(process->pid()),
- "--gui",
- "-p", QString::number(listeningPort)
- };
- auto basePath = globalSettings->get("JProfilerPath").toString();
-
-#ifdef Q_OS_WIN
- QString profilerProgram = QDir(basePath).absoluteFilePath("bin/jpenable.exe");
-#else
- QString profilerProgram = QDir(basePath).absoluteFilePath("bin/jpenable");
-#endif
-
- profiler->setArguments(profilerArgs);
- profiler->setProgram(profilerProgram);
-
- connect(profiler, SIGNAL(started()), SLOT(profilerStarted()));
- connect(profiler, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(profilerFinished(int,QProcess::ExitStatus)));
-
- m_profilerProcess = profiler;
- profiler->start();
-}
-
-void JProfilerFactory::registerSettings(SettingsObjectPtr settings)
-{
- settings->registerSetting("JProfilerPath");
- settings->registerSetting("JProfilerPort", 42042);
- globalSettings = settings;
-}
-
-BaseExternalTool *JProfilerFactory::createTool(InstancePtr instance, QObject *parent)
-{
- return new JProfiler(globalSettings, instance, parent);
-}
-
-bool JProfilerFactory::check(QString *error)
-{
- return check(globalSettings->get("JProfilerPath").toString(), error);
-}
-
-bool JProfilerFactory::check(const QString &path, QString *error)
-{
- if (path.isEmpty())
- {
- *error = QObject::tr("Empty path");
- return false;
- }
- QDir dir(path);
- if (!dir.exists())
- {
- *error = QObject::tr("Path does not exist");
- return false;
- }
- if (!dir.exists("bin") || !(dir.exists("bin/jprofiler") || dir.exists("bin/jprofiler.exe")) || !dir.exists("bin/agent.jar"))
- {
- *error = QObject::tr("Invalid JProfiler install");
- return false;
- }
- return true;
-}
-
-#include "JProfiler.moc"
diff --git a/libraries/logic/tools/JProfiler.h b/libraries/logic/tools/JProfiler.h
deleted file mode 100644
index d658d6c2..00000000
--- a/libraries/logic/tools/JProfiler.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "BaseProfiler.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT JProfilerFactory : public BaseProfilerFactory
-{
-public:
- QString name() const override { return "JProfiler"; }
- void registerSettings(SettingsObjectPtr settings) override;
- BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
- bool check(QString *error) override;
- bool check(const QString &path, QString *error) override;
-};
diff --git a/libraries/logic/tools/JVisualVM.cpp b/libraries/logic/tools/JVisualVM.cpp
deleted file mode 100644
index 169967d9..00000000
--- a/libraries/logic/tools/JVisualVM.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "JVisualVM.h"
-
-#include <QDir>
-#include <QStandardPaths>
-
-#include "settings/SettingsObject.h"
-#include "launch/LaunchTask.h"
-#include "BaseInstance.h"
-
-class JVisualVM : public BaseProfiler
-{
- Q_OBJECT
-public:
- JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
-
-private slots:
- void profilerStarted();
- void profilerFinished(int exit, QProcess::ExitStatus status);
-
-protected:
- void beginProfilingImpl(std::shared_ptr<LaunchTask> process);
-};
-
-
-JVisualVM::JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseProfiler(settings, instance, parent)
-{
-}
-
-void JVisualVM::profilerStarted()
-{
- emit readyToLaunch(tr("JVisualVM started"));
-}
-
-void JVisualVM::profilerFinished(int exit, QProcess::ExitStatus status)
-{
- if (status == QProcess::CrashExit)
- {
- emit abortLaunch(tr("Profiler aborted"));
- }
- if (m_profilerProcess)
- {
- m_profilerProcess->deleteLater();
- m_profilerProcess = 0;
- }
-}
-
-void JVisualVM::beginProfilingImpl(std::shared_ptr<LaunchTask> process)
-{
- QProcess *profiler = new QProcess(this);
- QStringList profilerArgs =
- {
- "--openpid", QString::number(process->pid())
- };
- auto programPath = globalSettings->get("JVisualVMPath").toString();
-
- profiler->setArguments(profilerArgs);
- profiler->setProgram(programPath);
-
- connect(profiler, SIGNAL(started()), SLOT(profilerStarted()));
- connect(profiler, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(profilerFinished(int,QProcess::ExitStatus)));
-
- profiler->start();
- m_profilerProcess = profiler;
-}
-
-void JVisualVMFactory::registerSettings(SettingsObjectPtr settings)
-{
- QString defaultValue = QStandardPaths::findExecutable("jvisualvm");
- if (defaultValue.isNull())
- {
- defaultValue = QStandardPaths::findExecutable("visualvm");
- }
- settings->registerSetting("JVisualVMPath", defaultValue);
- globalSettings = settings;
-}
-
-BaseExternalTool *JVisualVMFactory::createTool(InstancePtr instance, QObject *parent)
-{
- return new JVisualVM(globalSettings, instance, parent);
-}
-
-bool JVisualVMFactory::check(QString *error)
-{
- return check(globalSettings->get("JVisualVMPath").toString(), error);
-}
-
-bool JVisualVMFactory::check(const QString &path, QString *error)
-{
- if (path.isEmpty())
- {
- *error = QObject::tr("Empty path");
- return false;
- }
- if (!QDir::isAbsolutePath(path) || !QFileInfo(path).isExecutable() || !path.contains("visualvm"))
- {
- *error = QObject::tr("Invalid path to JVisualVM");
- return false;
- }
- return true;
-}
-
-#include "JVisualVM.moc"
diff --git a/libraries/logic/tools/JVisualVM.h b/libraries/logic/tools/JVisualVM.h
deleted file mode 100644
index 0674da13..00000000
--- a/libraries/logic/tools/JVisualVM.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "BaseProfiler.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT JVisualVMFactory : public BaseProfilerFactory
-{
-public:
- QString name() const override { return "JVisualVM"; }
- void registerSettings(SettingsObjectPtr settings) override;
- BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
- bool check(QString *error) override;
- bool check(const QString &path, QString *error) override;
-};
diff --git a/libraries/logic/tools/MCEditTool.cpp b/libraries/logic/tools/MCEditTool.cpp
deleted file mode 100644
index 32695c8d..00000000
--- a/libraries/logic/tools/MCEditTool.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#include "MCEditTool.h"
-
-#include <QDir>
-#include <QProcess>
-#include <QUrl>
-
-#include "settings/SettingsObject.h"
-#include "BaseInstance.h"
-#include "minecraft/MinecraftInstance.h"
-
-MCEditTool::MCEditTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseDetachedTool(settings, instance, parent)
-{
-}
-
-QString MCEditTool::getSave() const
-{
- // FIXME: mixing logic and UI!!!!
- auto mcInstance = std::dynamic_pointer_cast<MinecraftInstance>(m_instance);
- if(!mcInstance)
- {
- return QString();
- }
- QDir saves(mcInstance->minecraftRoot() + "/saves");
- QStringList worlds = saves.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- QMutableListIterator<QString> it(worlds);
- while (it.hasNext())
- {
- it.next();
- if (!QDir(saves.absoluteFilePath(it.value())).exists("level.dat"))
- {
- it.remove();
- }
- }
- bool ok = true;
- /*
- const QString save = QInputDialog::getItem(QApplication::activeWindow(), tr("MCEdit"), tr("Choose which world to open:"),
- worlds, 0, false, &ok);
- if (ok)
- {
- return saves.absoluteFilePath(save);
- }
- */
- return QString();
-}
-
-void MCEditTool::runImpl()
-{
- const QString mceditPath = globalSettings->get("MCEditPath").toString();
- const QString save = getSave();
- if (save.isNull())
- {
- return;
- }
-#ifdef Q_OS_OSX
- QProcess *process = new QProcess();
- connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), process, SLOT(deleteLater()));
- process->setProgram(mceditPath);
- process->setArguments(QStringList() << save);
- process->start();
-#else
- QDir mceditDir(mceditPath);
- QString program;
- #ifdef Q_OS_LINUX
- if (mceditDir.exists("mcedit.py"))
- {
- program = mceditDir.absoluteFilePath("mcedit.py");
- }
- else if (mceditDir.exists("mcedit.sh"))
- {
- program = mceditDir.absoluteFilePath("mcedit.sh");
- }
- #elif defined(Q_OS_WIN32)
- if (mceditDir.exists("mcedit.exe"))
- {
- program = mceditDir.absoluteFilePath("mcedit.exe");
- }
- else if (mceditDir.exists("mcedit2.exe"))
- {
- program = mceditDir.absoluteFilePath("mcedit2.exe");
- }
- #endif
- /*
- if(program.size())
- {
- DesktopServices::openFile(program, save, mceditPath);
- }
- */
-#endif
-}
-
-void MCEditFactory::registerSettings(SettingsObjectPtr settings)
-{
- settings->registerSetting("MCEditPath");
- globalSettings = settings;
-}
-BaseExternalTool *MCEditFactory::createTool(InstancePtr instance, QObject *parent)
-{
- return new MCEditTool(globalSettings, instance, parent);
-}
-bool MCEditFactory::check(QString *error)
-{
- return check(globalSettings->get("MCEditPath").toString(), error);
-}
-bool MCEditFactory::check(const QString &path, QString *error)
-{
- if (path.isEmpty())
- {
- *error = QObject::tr("Path is empty");
- return false;
- }
- const QDir dir(path);
- if (!dir.exists())
- {
- *error = QObject::tr("Path does not exist");
- return false;
- }
- if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && !dir.exists("mcedit2.exe"))
- {
- *error = QObject::tr("Path does not seem to be a MCEdit path");
- return false;
- }
- return true;
-}
diff --git a/libraries/logic/tools/MCEditTool.h b/libraries/logic/tools/MCEditTool.h
deleted file mode 100644
index c287f1ea..00000000
--- a/libraries/logic/tools/MCEditTool.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "BaseExternalTool.h"
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT MCEditTool : public BaseDetachedTool
-{
- Q_OBJECT
-public:
- explicit MCEditTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
-
-protected:
- QString getSave() const;
- void runImpl() override;
-};
-
-class MULTIMC_LOGIC_EXPORT MCEditFactory : public BaseDetachedToolFactory
-{
-public:
- QString name() const override { return "MCEdit"; }
- void registerSettings(SettingsObjectPtr settings) override;
- BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
- bool check(QString *error) override;
- bool check(const QString &path, QString *error) override;
-};
diff --git a/libraries/logic/trans/TranslationDownloader.cpp b/libraries/logic/trans/TranslationDownloader.cpp
deleted file mode 100644
index ee5c1fd2..00000000
--- a/libraries/logic/trans/TranslationDownloader.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "TranslationDownloader.h"
-#include "net/NetJob.h"
-#include "net/CacheDownload.h"
-#include "net/URLConstants.h"
-#include "Env.h"
-#include <QDebug>
-
-TranslationDownloader::TranslationDownloader()
-{
-}
-void TranslationDownloader::downloadTranslations()
-{
- qDebug() << "Downloading Translations Index...";
- m_index_job.reset(new NetJob("Translations Index"));
- m_index_task = ByteArrayDownload::make(QUrl("http://files.multimc.org/translations/index"));
- m_index_job->addNetAction(m_index_task);
- connect(m_index_job.get(), &NetJob::failed, this, &TranslationDownloader::indexFailed);
- connect(m_index_job.get(), &NetJob::succeeded, this, &TranslationDownloader::indexRecieved);
- m_index_job->start();
-}
-void TranslationDownloader::indexRecieved()
-{
- qDebug() << "Got translations index!";
- m_dl_job.reset(new NetJob("Translations"));
- QList<QByteArray> lines = m_index_task->m_data.split('\n');
- for (const auto line : lines)
- {
- if (!line.isEmpty())
- {
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + line);
- entry->setStale(true);
- CacheDownloadPtr dl = CacheDownload::make(
- QUrl(URLConstants::TRANSLATIONS_BASE_URL + line),
- entry);
- m_dl_job->addNetAction(dl);
- }
- }
- connect(m_dl_job.get(), &NetJob::succeeded, this, &TranslationDownloader::dlGood);
- connect(m_dl_job.get(), &NetJob::failed, this, &TranslationDownloader::dlFailed);
- m_dl_job->start();
-}
-void TranslationDownloader::dlFailed(QString reason)
-{
- qCritical() << "Translations Download Failed:" << reason;
-}
-void TranslationDownloader::dlGood()
-{
- qDebug() << "Got translations!";
-}
-void TranslationDownloader::indexFailed(QString reason)
-{
- qCritical() << "Translations Index Download Failed:" << reason;
-}
diff --git a/libraries/logic/trans/TranslationDownloader.h b/libraries/logic/trans/TranslationDownloader.h
deleted file mode 100644
index e7893805..00000000
--- a/libraries/logic/trans/TranslationDownloader.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <QList>
-#include <QUrl>
-#include <memory>
-#include <QObject>
-#include <net/NetJob.h>
-#include "multimc_logic_export.h"
-
-class ByteArrayDownload;
-class NetJob;
-
-class MULTIMC_LOGIC_EXPORT TranslationDownloader : public QObject
-{
- Q_OBJECT
-
-public:
- TranslationDownloader();
-
- void downloadTranslations();
-
-private slots:
- void indexRecieved();
- void indexFailed(QString reason);
- void dlFailed(QString reason);
- void dlGood();
-
-private:
- std::shared_ptr<ByteArrayDownload> m_index_task;
- NetJobPtr m_dl_job;
- NetJobPtr m_index_job;
-};
diff --git a/libraries/logic/updater/DownloadTask.cpp b/libraries/logic/updater/DownloadTask.cpp
deleted file mode 100644
index 6947e8bf..00000000
--- a/libraries/logic/updater/DownloadTask.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Copyright 2013-2014 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 "DownloadTask.h"
-
-#include "updater/UpdateChecker.h"
-#include "GoUpdate.h"
-#include "net/NetJob.h"
-
-#include <QFile>
-#include <QTemporaryDir>
-#include <QCryptographicHash>
-
-namespace GoUpdate
-{
-
-DownloadTask::DownloadTask(Status status, QString target, QObject *parent)
- : Task(parent), m_updateFilesDir(target)
-{
- m_status = status;
-
- m_updateFilesDir.setAutoRemove(false);
-}
-
-void DownloadTask::executeTask()
-{
- loadVersionInfo();
-}
-
-void DownloadTask::loadVersionInfo()
-{
- setStatus(tr("Loading version information..."));
-
- m_currentVersionFileListDownload.reset();
- m_newVersionFileListDownload.reset();
-
- NetJob *netJob = new NetJob("Version Info");
-
- // Find the index URL.
- QUrl newIndexUrl = QUrl(m_status.newRepoUrl).resolved(QString::number(m_status.newVersionId) + ".json");
- qDebug() << m_status.newRepoUrl << " turns into " << newIndexUrl;
-
- netJob->addNetAction(m_newVersionFileListDownload = ByteArrayDownload::make(newIndexUrl));
-
- // If we have a current version URL, get that one too.
- if (!m_status.currentRepoUrl.isEmpty())
- {
- QUrl cIndexUrl = QUrl(m_status.currentRepoUrl).resolved(QString::number(m_status.currentVersionId) + ".json");
- netJob->addNetAction(m_currentVersionFileListDownload = ByteArrayDownload::make(cIndexUrl));
- qDebug() << m_status.currentRepoUrl << " turns into " << cIndexUrl;
- }
-
- // connect signals and start the job
- connect(netJob, &NetJob::succeeded, this, &DownloadTask::processDownloadedVersionInfo);
- connect(netJob, &NetJob::failed, this, &DownloadTask::vinfoDownloadFailed);
- m_vinfoNetJob.reset(netJob);
- netJob->start();
-}
-
-void DownloadTask::vinfoDownloadFailed()
-{
- // Something failed. We really need the second download (current version info), so parse
- // downloads anyways as long as the first one succeeded.
- if (m_newVersionFileListDownload->m_status != Job_Failed)
- {
- processDownloadedVersionInfo();
- return;
- }
-
- // TODO: Give a more detailed error message.
- qCritical() << "Failed to download version info files.";
- emitFailed(tr("Failed to download version info files."));
-}
-
-void DownloadTask::processDownloadedVersionInfo()
-{
- VersionFileList m_currentVersionFileList;
- VersionFileList m_newVersionFileList;
-
- setStatus(tr("Reading file list for new version..."));
- qDebug() << "Reading file list for new version...";
- QString error;
- if (!parseVersionInfo(m_newVersionFileListDownload->m_data, m_newVersionFileList, error))
- {
- qCritical() << error;
- emitFailed(error);
- return;
- }
-
- // if we have the current version info, use it.
- if (m_currentVersionFileListDownload && m_currentVersionFileListDownload->m_status != Job_Failed)
- {
- setStatus(tr("Reading file list for current version..."));
- qDebug() << "Reading file list for current version...";
- // if this fails, it's not a complete loss.
- QString error;
- if(!parseVersionInfo( m_currentVersionFileListDownload->m_data, m_currentVersionFileList, error))
- {
- qDebug() << error << "This is not a fatal error.";
- }
- }
-
- // We don't need this any more.
- m_currentVersionFileListDownload.reset();
- m_newVersionFileListDownload.reset();
- m_vinfoNetJob.reset();
-
- setStatus(tr("Processing file lists - figuring out how to install the update..."));
-
- // make a new netjob for the actual update files
- NetJobPtr netJob (new NetJob("Update Files"));
-
- // fill netJob and operationList
- if (!processFileLists(m_currentVersionFileList, m_newVersionFileList, m_status.rootPath, m_updateFilesDir.path(), netJob, m_operations))
- {
- emitFailed(tr("Failed to process update lists..."));
- return;
- }
-
- // Now start the download.
- QObject::connect(netJob.get(), &NetJob::succeeded, this, &DownloadTask::fileDownloadFinished);
- QObject::connect(netJob.get(), &NetJob::progress, this, &DownloadTask::fileDownloadProgressChanged);
- QObject::connect(netJob.get(), &NetJob::failed, this, &DownloadTask::fileDownloadFailed);
-
- setStatus(tr("Downloading %1 update files.").arg(QString::number(netJob->size())));
- qDebug() << "Begin downloading update files to" << m_updateFilesDir.path();
- m_filesNetJob = netJob;
- m_filesNetJob->start();
-}
-
-void DownloadTask::fileDownloadFinished()
-{
- emitSucceeded();
-}
-
-void DownloadTask::fileDownloadFailed(QString reason)
-{
- qCritical() << "Failed to download update files:" << reason;
- emitFailed(tr("Failed to download update files: %1").arg(reason));
-}
-
-void DownloadTask::fileDownloadProgressChanged(qint64 current, qint64 total)
-{
- setProgress(current, total);
-}
-
-QString DownloadTask::updateFilesDir()
-{
- return m_updateFilesDir.path();
-}
-
-OperationList DownloadTask::operations()
-{
- return m_operations;
-}
-
-} \ No newline at end of file
diff --git a/libraries/logic/updater/DownloadTask.h b/libraries/logic/updater/DownloadTask.h
deleted file mode 100644
index 83b4a142..00000000
--- a/libraries/logic/updater/DownloadTask.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright 2013-2014 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "tasks/Task.h"
-#include "net/NetJob.h"
-#include "GoUpdate.h"
-
-#include "multimc_logic_export.h"
-
-namespace GoUpdate
-{
-/*!
- * The DownloadTask is a task that takes a given version ID and repository URL,
- * downloads that version's files from the repository, and prepares to install them.
- */
-class MULTIMC_LOGIC_EXPORT DownloadTask : public Task
-{
- Q_OBJECT
-
-public:
- /**
- * Create a download task
- *
- * target is a template - XXXXXX at the end will be replaced with a random generated string, ensuring uniqueness
- */
- explicit DownloadTask(Status status, QString target, QObject* parent = 0);
-
- /// Get the directory that will contain the update files.
- QString updateFilesDir();
-
- /// Get the list of operations that should be done
- OperationList operations();
-
- /// set updater download behavior
- void setUseLocalUpdater(bool useLocal);
-
-protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
-
- /*!
- * Downloads the version info files from the repository.
- * The files for both the current build, and the build that we're updating to need to be downloaded.
- * If the current version's info file can't be found, MultiMC will not delete files that
- * were removed between versions. It will still replace files that have changed, however.
- * Note that although the repository URL for the current version is not given to the update task,
- * the task will attempt to look it up in the UpdateChecker's channel list.
- * If an error occurs here, the function will call emitFailed and return false.
- */
- void loadVersionInfo();
-
- NetJobPtr m_vinfoNetJob;
- ByteArrayDownloadPtr m_currentVersionFileListDownload;
- ByteArrayDownloadPtr m_newVersionFileListDownload;
-
- NetJobPtr m_filesNetJob;
-
- Status m_status;
-
- OperationList m_operations;
-
- /*!
- * Temporary directory to store update files in.
- * This will be set to not auto delete. Task will fail if this fails to be created.
- */
- QTemporaryDir m_updateFilesDir;
-
-protected slots:
- /*!
- * This function is called when version information is finished downloading
- * and at least the new file list download succeeded
- */
- void processDownloadedVersionInfo();
- void vinfoDownloadFailed();
-
- void fileDownloadFinished();
- void fileDownloadFailed(QString reason);
- void fileDownloadProgressChanged(qint64 current, qint64 total);
-};
-
-} \ No newline at end of file
diff --git a/libraries/logic/updater/GoUpdate.cpp b/libraries/logic/updater/GoUpdate.cpp
deleted file mode 100644
index 60d50e04..00000000
--- a/libraries/logic/updater/GoUpdate.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-#include "GoUpdate.h"
-#include <QDebug>
-#include <QDomDocument>
-#include <QFile>
-#include <Env.h>
-#include <FileSystem.h>
-
-namespace GoUpdate
-{
-
-bool parseVersionInfo(const QByteArray &data, VersionFileList &list, QString &error)
-{
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- error = QString("Failed to parse version info JSON: %1 at %2")
- .arg(jsonError.errorString())
- .arg(jsonError.offset);
- qCritical() << error;
- return false;
- }
-
- QJsonObject json = jsonDoc.object();
-
- qDebug() << data;
- qDebug() << "Loading version info from JSON.";
- QJsonArray filesArray = json.value("Files").toArray();
- for (QJsonValue fileValue : filesArray)
- {
- QJsonObject fileObj = fileValue.toObject();
-
- QString file_path = fileObj.value("Path").toString();
-#ifdef Q_OS_MAC
- // On OSX, the paths for the updater need to be fixed.
- // basically, anything that isn't in the .app folder is ignored.
- // everything else is changed so the code that processes the files actually finds
- // them and puts the replacements in the right spots.
- fixPathForOSX(file_path);
-#endif
- VersionFileEntry file{file_path, fileObj.value("Perms").toVariant().toInt(),
- FileSourceList(), fileObj.value("MD5").toString(), };
- qDebug() << "File" << file.path << "with perms" << file.mode;
-
- QJsonArray sourceArray = fileObj.value("Sources").toArray();
- for (QJsonValue val : sourceArray)
- {
- QJsonObject sourceObj = val.toObject();
-
- QString type = sourceObj.value("SourceType").toString();
- if (type == "http")
- {
- file.sources.append(FileSource("http", sourceObj.value("Url").toString()));
- }
- else
- {
- qWarning() << "Unknown source type" << type << "ignored.";
- }
- }
-
- qDebug() << "Loaded info for" << file.path;
-
- list.append(file);
- }
-
- return true;
-}
-
-bool processFileLists
-(
- const VersionFileList &currentVersion,
- const VersionFileList &newVersion,
- const QString &rootPath,
- const QString &tempPath,
- NetJobPtr job,
- OperationList &ops
-)
-{
- // First, if we've loaded the current version's file list, we need to iterate through it and
- // delete anything in the current one version's list that isn't in the new version's list.
- for (VersionFileEntry entry : currentVersion)
- {
- QFileInfo toDelete(FS::PathCombine(rootPath, entry.path));
- if (!toDelete.exists())
- {
- qCritical() << "Expected file " << toDelete.absoluteFilePath()
- << " doesn't exist!";
- }
- bool keep = false;
-
- //
- for (VersionFileEntry newEntry : newVersion)
- {
- if (newEntry.path == entry.path)
- {
- qDebug() << "Not deleting" << entry.path
- << "because it is still present in the new version.";
- keep = true;
- break;
- }
- }
-
- // If the loop reaches the end and we didn't find a match, delete the file.
- if (!keep)
- {
- if (toDelete.exists())
- ops.append(Operation::DeleteOp(entry.path));
- }
- }
-
- // Next, check each file in MultiMC's folder and see if we need to update them.
- for (VersionFileEntry entry : newVersion)
- {
- // TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
- // way to do this in the background.
- QString fileMD5;
- QString realEntryPath = FS::PathCombine(rootPath, entry.path);
- QFile entryFile(realEntryPath);
- QFileInfo entryInfo(realEntryPath);
-
- bool needs_upgrade = false;
- if (!entryFile.exists())
- {
- needs_upgrade = true;
- }
- else
- {
- bool pass = true;
- if (!entryInfo.isReadable())
- {
- qCritical() << "File " << realEntryPath << " is not readable.";
- pass = false;
- }
- if (!entryInfo.isWritable())
- {
- qCritical() << "File " << realEntryPath << " is not writable.";
- pass = false;
- }
- if (!entryFile.open(QFile::ReadOnly))
- {
- qCritical() << "File " << realEntryPath << " cannot be opened for reading.";
- pass = false;
- }
- if (!pass)
- {
- ops.clear();
- return false;
- }
- }
-
- if(!needs_upgrade)
- {
- QCryptographicHash hash(QCryptographicHash::Md5);
- auto foo = entryFile.readAll();
-
- hash.addData(foo);
- fileMD5 = hash.result().toHex();
- if ((fileMD5 != entry.md5))
- {
- qDebug() << "MD5Sum does not match!";
- qDebug() << "Expected:'" << entry.md5 << "'";
- qDebug() << "Got: '" << fileMD5 << "'";
- needs_upgrade = true;
- }
- }
-
- // skip file. it doesn't need an upgrade.
- if (!needs_upgrade)
- {
- qDebug() << "File" << realEntryPath << " does not need updating.";
- continue;
- }
-
- // yep. this file actually needs an upgrade. PROCEED.
- qDebug() << "Found file" << realEntryPath << " that needs updating.";
-
- // Go through the sources list and find one to use.
- // TODO: Make a NetAction that takes a source list and tries each of them until one
- // works. For now, we'll just use the first http one.
- for (FileSource source : entry.sources)
- {
- if (source.type != "http")
- continue;
-
- qDebug() << "Will download" << entry.path << "from" << source.url;
-
- // Download it to updatedir/<filepath>-<md5> where filepath is the file's
- // path with slashes replaced by underscores.
- QString dlPath = FS::PathCombine(tempPath, QString(entry.path).replace("/", "_"));
-
- // We need to download the file to the updatefiles folder and add a task
- // to copy it to its install path.
- auto download = MD5EtagDownload::make(source.url, dlPath);
- download->m_expected_md5 = entry.md5;
- job->addNetAction(download);
- ops.append(Operation::CopyOp(dlPath, entry.path, entry.mode));
- }
- }
- return true;
-}
-
-bool fixPathForOSX(QString &path)
-{
- if (path.startsWith("MultiMC.app/"))
- {
- // remove the prefix and add a new, more appropriate one.
- path.remove(0, 12);
- return true;
- }
- else
- {
- qCritical() << "Update path not within .app: " << path;
- return false;
- }
-}
-} \ No newline at end of file
diff --git a/libraries/logic/updater/GoUpdate.h b/libraries/logic/updater/GoUpdate.h
deleted file mode 100644
index b8a534de..00000000
--- a/libraries/logic/updater/GoUpdate.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#pragma once
-#include <QByteArray>
-#include <net/NetJob.h>
-
-#include "multimc_logic_export.h"
-
-namespace GoUpdate
-{
-
-/**
- * A temporary object exchanged between updated checker and the actual update task
- */
-struct MULTIMC_LOGIC_EXPORT Status
-{
- bool updateAvailable = false;
-
- int newVersionId = -1;
- QString newRepoUrl;
-
- int currentVersionId = -1;
- QString currentRepoUrl;
-
- // path to the root of the application
- QString rootPath;
-};
-
-/**
- * Struct that describes an entry in a VersionFileEntry's `Sources` list.
- */
-struct MULTIMC_LOGIC_EXPORT FileSource
-{
- FileSource(QString type, QString url, QString compression="")
- {
- this->type = type;
- this->url = url;
- this->compressionType = compression;
- }
-
- bool operator==(const FileSource &f2) const
- {
- return type == f2.type && url == f2.url && compressionType == f2.compressionType;
- }
-
- QString type;
- QString url;
- QString compressionType;
-};
-typedef QList<FileSource> FileSourceList;
-
-/**
- * Structure that describes an entry in a GoUpdate version's `Files` list.
- */
-struct MULTIMC_LOGIC_EXPORT VersionFileEntry
-{
- QString path;
- int mode;
- FileSourceList sources;
- QString md5;
- bool operator==(const VersionFileEntry &v2) const
- {
- return path == v2.path && mode == v2.mode && sources == v2.sources && md5 == v2.md5;
- }
-};
-typedef QList<VersionFileEntry> VersionFileList;
-
-/**
- * Structure that describes an operation to perform when installing updates.
- */
-struct MULTIMC_LOGIC_EXPORT Operation
-{
- static Operation CopyOp(QString fsource, QString fdest, int fmode=0644)
- {
- return Operation{OP_REPLACE, fsource, fdest, fmode};
- }
- static Operation DeleteOp(QString file)
- {
- return Operation{OP_DELETE, file, "", 0644};
- }
-
- // FIXME: for some types, some of the other fields are irrelevant!
- bool operator==(const Operation &u2) const
- {
- return type == u2.type && file == u2.file && dest == u2.dest && mode == u2.mode;
- }
-
- //! Specifies the type of operation that this is.
- enum Type
- {
- OP_REPLACE,
- OP_DELETE,
- } type;
-
- //! The file to operate on.
- QString file;
-
- //! The destination file.
- QString dest;
-
- //! The mode to change the source file to.
- int mode;
-};
-typedef QList<Operation> OperationList;
-
-/**
- * Loads the file list from the given version info JSON object into the given list.
- */
-bool MULTIMC_LOGIC_EXPORT parseVersionInfo(const QByteArray &data, VersionFileList& list, QString &error);
-
-/*!
- * Takes a list of file entries for the current version's files and the new version's files
- * and populates the downloadList and operationList with information about how to download and install the update.
- */
-bool MULTIMC_LOGIC_EXPORT processFileLists
-(
- const VersionFileList &currentVersion,
- const VersionFileList &newVersion,
- const QString &rootPath,
- const QString &tempPath,
- NetJobPtr job,
- OperationList &ops
-);
-
-/*!
- * This fixes destination paths for OSX - removes 'MultiMC.app' prefix
- * The updater runs in MultiMC.app/Contents/MacOs by default
- * The destination paths are such as this: MultiMC.app/blah/blah
- *
- * @return false if the path couldn't be fixed (is invalid)
- */
-bool MULTIMC_LOGIC_EXPORT fixPathForOSX(QString &path);
-
-}
-Q_DECLARE_METATYPE(GoUpdate::Status); \ No newline at end of file
diff --git a/libraries/logic/updater/UpdateChecker.cpp b/libraries/logic/updater/UpdateChecker.cpp
deleted file mode 100644
index 1cdac916..00000000
--- a/libraries/logic/updater/UpdateChecker.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/* Copyright 2013-2015 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 "UpdateChecker.h"
-
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <QDebug>
-
-#define API_VERSION 0
-#define CHANLIST_FORMAT 0
-
-UpdateChecker::UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild)
-{
- m_channelListUrl = channelListUrl;
- m_currentChannel = currentChannel;
- m_currentBuild = currentBuild;
-
- m_updateChecking = false;
- m_chanListLoading = false;
- m_checkUpdateWaiting = false;
- m_chanListLoaded = false;
-}
-
-QList<UpdateChecker::ChannelListEntry> UpdateChecker::getChannelList() const
-{
- return m_channels;
-}
-
-bool UpdateChecker::hasChannels() const
-{
- return !m_channels.isEmpty();
-}
-
-void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
-{
- qDebug() << "Checking for updates.";
-
- // If the channel list hasn't loaded yet, load it and defer checking for updates until
- // later.
- if (!m_chanListLoaded)
- {
- qDebug() << "Channel list isn't loaded yet. Loading channel list and deferring "
- "update check.";
- m_checkUpdateWaiting = true;
- m_deferredUpdateChannel = updateChannel;
- updateChanList(notifyNoUpdate);
- return;
- }
-
- if (m_updateChecking)
- {
- qDebug() << "Ignoring update check request. Already checking for updates.";
- return;
- }
-
- m_updateChecking = true;
-
- // Find the desired channel within the channel list and get its repo URL. If if cannot be
- // found, error.
- m_newRepoUrl = "";
- for (ChannelListEntry entry : m_channels)
- {
- if (entry.id == updateChannel)
- m_newRepoUrl = entry.url;
- if (entry.id == m_currentChannel)
- m_currentRepoUrl = entry.url;
- }
-
- qDebug() << "m_repoUrl = " << m_newRepoUrl;
-
- // If we didn't find our channel, error.
- if (m_newRepoUrl.isEmpty())
- {
- qCritical() << "m_repoUrl is empty!";
- emit updateCheckFailed();
- return;
- }
-
- QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
-
- auto job = new NetJob("GoUpdate Repository Index");
- job->addNetAction(ByteArrayDownload::make(indexUrl));
- connect(job, &NetJob::succeeded, [this, notifyNoUpdate]()
- { updateCheckFinished(notifyNoUpdate); });
- connect(job, &NetJob::failed, this, &UpdateChecker::updateCheckFailed);
- indexJob.reset(job);
- job->start();
-}
-
-void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
-{
- qDebug() << "Finished downloading repo index. Checking for new versions.";
-
- QJsonParseError jsonError;
- QByteArray data;
- {
- ByteArrayDownloadPtr dl =
- std::dynamic_pointer_cast<ByteArrayDownload>(indexJob->first());
- data = dl->m_data;
- indexJob.reset();
- }
-
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject())
- {
- qCritical() << "Failed to parse GoUpdate repository index. JSON error"
- << jsonError.errorString() << "at offset" << jsonError.offset;
- return;
- }
-
- QJsonObject object = jsonDoc.object();
-
- bool success = false;
- int apiVersion = object.value("ApiVersion").toVariant().toInt(&success);
- if (apiVersion != API_VERSION || !success)
- {
- qCritical() << "Failed to check for updates. API version mismatch. We're using"
- << API_VERSION << "server has" << apiVersion;
- return;
- }
-
- qDebug() << "Processing repository version list.";
- QJsonObject newestVersion;
- QJsonArray versions = object.value("Versions").toArray();
- for (QJsonValue versionVal : versions)
- {
- QJsonObject version = versionVal.toObject();
- if (newestVersion.value("Id").toVariant().toInt() <
- version.value("Id").toVariant().toInt())
- {
- newestVersion = version;
- }
- }
-
- // We've got the version with the greatest ID number. Now compare it to our current build
- // number and update if they're different.
- int newBuildNumber = newestVersion.value("Id").toVariant().toInt();
- if (newBuildNumber != m_currentBuild)
- {
- qDebug() << "Found newer version with ID" << newBuildNumber;
- // Update!
- GoUpdate::Status updateStatus;
- updateStatus.updateAvailable = true;
- updateStatus.currentVersionId = m_currentBuild;
- updateStatus.currentRepoUrl = m_currentRepoUrl;
- updateStatus.newVersionId = newBuildNumber;
- updateStatus.newRepoUrl = m_newRepoUrl;
- emit updateAvailable(updateStatus);
- }
- else if (notifyNoUpdate)
- {
- emit noUpdateFound();
- }
-
- m_updateChecking = false;
-}
-
-void UpdateChecker::updateCheckFailed()
-{
- qCritical() << "Update check failed for reasons unknown.";
-}
-
-void UpdateChecker::updateChanList(bool notifyNoUpdate)
-{
- qDebug() << "Loading the channel list.";
-
- if (m_channelListUrl.isEmpty())
- {
- qCritical() << "Failed to update channel list. No channel list URL set."
- << "If you'd like to use MultiMC's update system, please pass the channel "
- "list URL to CMake at compile time.";
- return;
- }
-
- m_chanListLoading = true;
- NetJob *job = new NetJob("Update System Channel List");
- job->addNetAction(ByteArrayDownload::make(QUrl(m_channelListUrl)));
- connect(job, &NetJob::succeeded, [this, notifyNoUpdate]()
- { chanListDownloadFinished(notifyNoUpdate); });
- QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
- chanListJob.reset(job);
- job->start();
-}
-
-void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)
-{
- QByteArray data;
- {
- ByteArrayDownloadPtr dl =
- std::dynamic_pointer_cast<ByteArrayDownload>(chanListJob->first());
- data = dl->m_data;
- chanListJob.reset();
- }
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- // TODO: Report errors to the user.
- qCritical() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at"
- << jsonError.offset;
- return;
- }
-
- QJsonObject object = jsonDoc.object();
-
- bool success = false;
- int formatVersion = object.value("format_version").toVariant().toInt(&success);
- if (formatVersion != CHANLIST_FORMAT || !success)
- {
- qCritical()
- << "Failed to check for updates. Channel list format version mismatch. We're using"
- << CHANLIST_FORMAT << "server has" << formatVersion;
- return;
- }
-
- // Load channels into a temporary array.
- QList<ChannelListEntry> loadedChannels;
- QJsonArray channelArray = object.value("channels").toArray();
- for (QJsonValue chanVal : channelArray)
- {
- QJsonObject channelObj = chanVal.toObject();
- ChannelListEntry entry{channelObj.value("id").toVariant().toString(),
- channelObj.value("name").toVariant().toString(),
- channelObj.value("description").toVariant().toString(),
- channelObj.value("url").toVariant().toString()};
- if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty())
- {
- qCritical() << "Channel list entry with empty ID, name, or URL. Skipping.";
- continue;
- }
- loadedChannels.append(entry);
- }
-
- // Swap the channel list we just loaded into the object's channel list.
- m_channels.swap(loadedChannels);
-
- m_chanListLoading = false;
- m_chanListLoaded = true;
- qDebug() << "Successfully loaded UpdateChecker channel list.";
-
- // If we're waiting to check for updates, do that now.
- if (m_checkUpdateWaiting)
- checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate);
-
- emit channelListLoaded();
-}
-
-void UpdateChecker::chanListDownloadFailed(QString reason)
-{
- m_chanListLoading = false;
- qCritical() << QString("Failed to download channel list: %1").arg(reason);
- emit channelListLoaded();
-}
-
diff --git a/libraries/logic/updater/UpdateChecker.h b/libraries/logic/updater/UpdateChecker.h
deleted file mode 100644
index c7fad10e..00000000
--- a/libraries/logic/updater/UpdateChecker.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright 2013-2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "net/NetJob.h"
-#include "GoUpdate.h"
-
-#include <QUrl>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT UpdateChecker : public QObject
-{
- Q_OBJECT
-
-public:
- UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild);
- void checkForUpdate(QString updateChannel, bool notifyNoUpdate);
-
- /*!
- * Causes the update checker to download the channel list from the URL specified in config.h (generated by CMake).
- * If this isn't called before checkForUpdate(), it will automatically be called.
- */
- void updateChanList(bool notifyNoUpdate);
-
- /*!
- * An entry in the channel list.
- */
- struct ChannelListEntry
- {
- QString id;
- QString name;
- QString description;
- QString url;
- };
-
- /*!
- * Returns a the current channel list.
- * If the channel list hasn't been loaded, this list will be empty.
- */
- QList<ChannelListEntry> getChannelList() const;
-
- /*!
- * Returns false if the channel list is empty.
- */
- bool hasChannels() const;
-
-signals:
- //! Signal emitted when an update is available. Passes the URL for the repo and the ID and name for the version.
- void updateAvailable(GoUpdate::Status status);
-
- //! Signal emitted when the channel list finishes loading or fails to load.
- void channelListLoaded();
-
- void noUpdateFound();
-
-private slots:
- void updateCheckFinished(bool notifyNoUpdate);
- void updateCheckFailed();
-
- void chanListDownloadFinished(bool notifyNoUpdate);
- void chanListDownloadFailed(QString reason);
-
-private:
- friend class UpdateCheckerTest;
-
- NetJobPtr indexJob;
- NetJobPtr chanListJob;
-
- QString m_channelListUrl;
-
- QList<ChannelListEntry> m_channels;
-
- /*!
- * True while the system is checking for updates.
- * If checkForUpdate is called while this is true, it will be ignored.
- */
- bool m_updateChecking;
-
- /*!
- * True if the channel list has loaded.
- * If this is false, trying to check for updates will call updateChanList first.
- */
- bool m_chanListLoaded;
-
- /*!
- * Set to true while the channel list is currently loading.
- */
- bool m_chanListLoading;
-
- /*!
- * Set to true when checkForUpdate is called while the channel list isn't loaded.
- * When the channel list finishes loading, if this is true, the update checker will check for updates.
- */
- bool m_checkUpdateWaiting;
-
- /*!
- * if m_checkUpdateWaiting, this is the last used update channel
- */
- QString m_deferredUpdateChannel;
-
- int m_currentBuild = -1;
- QString m_currentChannel;
- QString m_currentRepoUrl;
-
- QString m_newRepoUrl;
-};
-
diff --git a/libraries/logic/wonko/BaseWonkoEntity.cpp b/libraries/logic/wonko/BaseWonkoEntity.cpp
deleted file mode 100644
index f5c59363..00000000
--- a/libraries/logic/wonko/BaseWonkoEntity.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2015 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 "BaseWonkoEntity.h"
-
-#include "Json.h"
-#include "WonkoUtil.h"
-
-BaseWonkoEntity::~BaseWonkoEntity()
-{
-}
-
-void BaseWonkoEntity::store() const
-{
- Json::write(serialized(), Wonko::localWonkoDir().absoluteFilePath(localFilename()));
-}
-
-void BaseWonkoEntity::notifyLocalLoadComplete()
-{
- m_localLoaded = true;
- store();
-}
-void BaseWonkoEntity::notifyRemoteLoadComplete()
-{
- m_remoteLoaded = true;
- store();
-}
diff --git a/libraries/logic/wonko/BaseWonkoEntity.h b/libraries/logic/wonko/BaseWonkoEntity.h
deleted file mode 100644
index 191b4184..00000000
--- a/libraries/logic/wonko/BaseWonkoEntity.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QObject>
-#include <memory>
-
-#include "multimc_logic_export.h"
-
-class Task;
-
-class MULTIMC_LOGIC_EXPORT BaseWonkoEntity
-{
-public:
- virtual ~BaseWonkoEntity();
-
- using Ptr = std::shared_ptr<BaseWonkoEntity>;
-
- virtual std::unique_ptr<Task> remoteUpdateTask() = 0;
- virtual std::unique_ptr<Task> localUpdateTask() = 0;
- virtual void merge(const std::shared_ptr<BaseWonkoEntity> &other) = 0;
-
- void store() const;
- virtual QString localFilename() const = 0;
- virtual QJsonObject serialized() const = 0;
-
- bool isComplete() const { return m_localLoaded || m_remoteLoaded; }
-
- bool isLocalLoaded() const { return m_localLoaded; }
- bool isRemoteLoaded() const { return m_remoteLoaded; }
-
- void notifyLocalLoadComplete();
- void notifyRemoteLoadComplete();
-
-private:
- bool m_localLoaded = false;
- bool m_remoteLoaded = false;
-};
diff --git a/libraries/logic/wonko/WonkoIndex.cpp b/libraries/logic/wonko/WonkoIndex.cpp
deleted file mode 100644
index 8306af84..00000000
--- a/libraries/logic/wonko/WonkoIndex.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/* Copyright 2015 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 "WonkoIndex.h"
-
-#include "WonkoVersionList.h"
-#include "tasks/BaseWonkoEntityLocalLoadTask.h"
-#include "tasks/BaseWonkoEntityRemoteLoadTask.h"
-#include "format/WonkoFormat.h"
-
-WonkoIndex::WonkoIndex(QObject *parent)
- : QAbstractListModel(parent)
-{
-}
-WonkoIndex::WonkoIndex(const QVector<WonkoVersionListPtr> &lists, QObject *parent)
- : QAbstractListModel(parent), m_lists(lists)
-{
- for (int i = 0; i < m_lists.size(); ++i)
- {
- m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
- connectVersionList(i, m_lists.at(i));
- }
-}
-
-QVariant WonkoIndex::data(const QModelIndex &index, int role) const
-{
- if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size())
- {
- return QVariant();
- }
-
- WonkoVersionListPtr list = m_lists.at(index.row());
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case 0: return list->humanReadable();
- default: break;
- }
- case UidRole: return list->uid();
- case NameRole: return list->name();
- case ListPtrRole: return QVariant::fromValue(list);
- }
- return QVariant();
-}
-int WonkoIndex::rowCount(const QModelIndex &parent) const
-{
- return m_lists.size();
-}
-int WonkoIndex::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-QVariant WonkoIndex::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0)
- {
- return tr("Name");
- }
- else
- {
- return QVariant();
- }
-}
-
-std::unique_ptr<Task> WonkoIndex::remoteUpdateTask()
-{
- return std::unique_ptr<WonkoIndexRemoteLoadTask>(new WonkoIndexRemoteLoadTask(this, this));
-}
-std::unique_ptr<Task> WonkoIndex::localUpdateTask()
-{
- return std::unique_ptr<WonkoIndexLocalLoadTask>(new WonkoIndexLocalLoadTask(this, this));
-}
-
-QJsonObject WonkoIndex::serialized() const
-{
- return WonkoFormat::serializeIndex(this);
-}
-
-bool WonkoIndex::hasUid(const QString &uid) const
-{
- return m_uids.contains(uid);
-}
-WonkoVersionListPtr WonkoIndex::getList(const QString &uid) const
-{
- return m_uids.value(uid, nullptr);
-}
-WonkoVersionListPtr WonkoIndex::getListGuaranteed(const QString &uid) const
-{
- return m_uids.value(uid, std::make_shared<WonkoVersionList>(uid));
-}
-
-void WonkoIndex::merge(const Ptr &other)
-{
- const QVector<WonkoVersionListPtr> lists = std::dynamic_pointer_cast<WonkoIndex>(other)->m_lists;
- // initial load, no need to merge
- if (m_lists.isEmpty())
- {
- beginResetModel();
- m_lists = lists;
- for (int i = 0; i < lists.size(); ++i)
- {
- m_uids.insert(lists.at(i)->uid(), lists.at(i));
- connectVersionList(i, lists.at(i));
- }
- endResetModel();
- }
- else
- {
- for (const WonkoVersionListPtr &list : lists)
- {
- if (m_uids.contains(list->uid()))
- {
- m_uids[list->uid()]->merge(list);
- }
- else
- {
- beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size());
- connectVersionList(m_lists.size(), list);
- m_lists.append(list);
- m_uids.insert(list->uid(), list);
- endInsertRows();
- }
- }
- }
-}
-
-void WonkoIndex::connectVersionList(const int row, const WonkoVersionListPtr &list)
-{
- connect(list.get(), &WonkoVersionList::nameChanged, this, [this, row]()
- {
- emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole);
- });
-}
diff --git a/libraries/logic/wonko/WonkoIndex.h b/libraries/logic/wonko/WonkoIndex.h
deleted file mode 100644
index 8b149c7d..00000000
--- a/libraries/logic/wonko/WonkoIndex.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QAbstractListModel>
-#include <memory>
-
-#include "BaseWonkoEntity.h"
-
-#include "multimc_logic_export.h"
-
-class Task;
-using WonkoVersionListPtr = std::shared_ptr<class WonkoVersionList>;
-
-class MULTIMC_LOGIC_EXPORT WonkoIndex : public QAbstractListModel, public BaseWonkoEntity
-{
- Q_OBJECT
-public:
- explicit WonkoIndex(QObject *parent = nullptr);
- explicit WonkoIndex(const QVector<WonkoVersionListPtr> &lists, QObject *parent = nullptr);
-
- enum
- {
- UidRole = Qt::UserRole,
- NameRole,
- ListPtrRole
- };
-
- QVariant data(const QModelIndex &index, int role) const override;
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
-
- std::unique_ptr<Task> remoteUpdateTask() override;
- std::unique_ptr<Task> localUpdateTask() override;
-
- QString localFilename() const override { return "index.json"; }
- QJsonObject serialized() const override;
-
- // queries
- bool hasUid(const QString &uid) const;
- WonkoVersionListPtr getList(const QString &uid) const;
- WonkoVersionListPtr getListGuaranteed(const QString &uid) const;
-
- QVector<WonkoVersionListPtr> lists() const { return m_lists; }
-
-public: // for usage by parsers only
- void merge(const BaseWonkoEntity::Ptr &other);
-
-private:
- QVector<WonkoVersionListPtr> m_lists;
- QHash<QString, WonkoVersionListPtr> m_uids;
-
- void connectVersionList(const int row, const WonkoVersionListPtr &list);
-};
diff --git a/libraries/logic/wonko/WonkoReference.cpp b/libraries/logic/wonko/WonkoReference.cpp
deleted file mode 100644
index 519d59aa..00000000
--- a/libraries/logic/wonko/WonkoReference.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2015 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 "WonkoReference.h"
-
-WonkoReference::WonkoReference(const QString &uid)
- : m_uid(uid)
-{
-}
-
-QString WonkoReference::uid() const
-{
- return m_uid;
-}
-
-QString WonkoReference::version() const
-{
- return m_version;
-}
-void WonkoReference::setVersion(const QString &version)
-{
- m_version = version;
-}
-
-bool WonkoReference::operator==(const WonkoReference &other) const
-{
- return m_uid == other.m_uid && m_version == other.m_version;
-}
-bool WonkoReference::operator!=(const WonkoReference &other) const
-{
- return m_uid != other.m_uid || m_version != other.m_version;
-}
diff --git a/libraries/logic/wonko/WonkoReference.h b/libraries/logic/wonko/WonkoReference.h
deleted file mode 100644
index 73a85d76..00000000
--- a/libraries/logic/wonko/WonkoReference.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-#include <QMetaType>
-
-#include "multimc_logic_export.h"
-
-class MULTIMC_LOGIC_EXPORT WonkoReference
-{
-public:
- WonkoReference() {}
- explicit WonkoReference(const QString &uid);
-
- QString uid() const;
-
- QString version() const;
- void setVersion(const QString &version);
-
- bool operator==(const WonkoReference &other) const;
- bool operator!=(const WonkoReference &other) const;
-
-private:
- QString m_uid;
- QString m_version;
-};
-Q_DECLARE_METATYPE(WonkoReference)
diff --git a/libraries/logic/wonko/WonkoUtil.cpp b/libraries/logic/wonko/WonkoUtil.cpp
deleted file mode 100644
index 94726c6b..00000000
--- a/libraries/logic/wonko/WonkoUtil.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright 2015 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 "WonkoUtil.h"
-
-#include <QUrl>
-#include <QDir>
-
-#include "Env.h"
-
-namespace Wonko
-{
-QUrl rootUrl()
-{
- return ENV.wonkoRootUrl();
-}
-QUrl indexUrl()
-{
- return rootUrl().resolved(QStringLiteral("index.json"));
-}
-QUrl versionListUrl(const QString &uid)
-{
- return rootUrl().resolved(uid + ".json");
-}
-QUrl versionUrl(const QString &uid, const QString &version)
-{
- return rootUrl().resolved(uid + "/" + version + ".json");
-}
-
-QDir localWonkoDir()
-{
- return QDir("wonko");
-}
-
-}
diff --git a/libraries/logic/wonko/WonkoUtil.h b/libraries/logic/wonko/WonkoUtil.h
deleted file mode 100644
index b618ab71..00000000
--- a/libraries/logic/wonko/WonkoUtil.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "multimc_logic_export.h"
-
-class QUrl;
-class QString;
-class QDir;
-
-namespace Wonko
-{
-MULTIMC_LOGIC_EXPORT QUrl rootUrl();
-MULTIMC_LOGIC_EXPORT QUrl indexUrl();
-MULTIMC_LOGIC_EXPORT QUrl versionListUrl(const QString &uid);
-MULTIMC_LOGIC_EXPORT QUrl versionUrl(const QString &uid, const QString &version);
-MULTIMC_LOGIC_EXPORT QDir localWonkoDir();
-}
diff --git a/libraries/logic/wonko/WonkoVersion.cpp b/libraries/logic/wonko/WonkoVersion.cpp
deleted file mode 100644
index 7b7da86c..00000000
--- a/libraries/logic/wonko/WonkoVersion.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright 2015 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 "WonkoVersion.h"
-
-#include <QDateTime>
-
-#include "tasks/BaseWonkoEntityLocalLoadTask.h"
-#include "tasks/BaseWonkoEntityRemoteLoadTask.h"
-#include "format/WonkoFormat.h"
-
-WonkoVersion::WonkoVersion(const QString &uid, const QString &version)
- : BaseVersion(), m_uid(uid), m_version(version)
-{
-}
-
-QString WonkoVersion::descriptor()
-{
- return m_version;
-}
-QString WonkoVersion::name()
-{
- return m_version;
-}
-QString WonkoVersion::typeString() const
-{
- return m_type;
-}
-
-QDateTime WonkoVersion::time() const
-{
- return QDateTime::fromMSecsSinceEpoch(m_time * 1000, Qt::UTC);
-}
-
-std::unique_ptr<Task> WonkoVersion::remoteUpdateTask()
-{
- return std::unique_ptr<WonkoVersionRemoteLoadTask>(new WonkoVersionRemoteLoadTask(this, this));
-}
-std::unique_ptr<Task> WonkoVersion::localUpdateTask()
-{
- return std::unique_ptr<WonkoVersionLocalLoadTask>(new WonkoVersionLocalLoadTask(this, this));
-}
-
-void WonkoVersion::merge(const std::shared_ptr<BaseWonkoEntity> &other)
-{
- WonkoVersionPtr version = std::dynamic_pointer_cast<WonkoVersion>(other);
- if (m_type != version->m_type)
- {
- setType(version->m_type);
- }
- if (m_time != version->m_time)
- {
- setTime(version->m_time);
- }
- if (m_requires != version->m_requires)
- {
- setRequires(version->m_requires);
- }
-
- setData(version->m_data);
-}
-
-QString WonkoVersion::localFilename() const
-{
- return m_uid + '/' + m_version + ".json";
-}
-QJsonObject WonkoVersion::serialized() const
-{
- return WonkoFormat::serializeVersion(this);
-}
-
-void WonkoVersion::setType(const QString &type)
-{
- m_type = type;
- emit typeChanged();
-}
-void WonkoVersion::setTime(const qint64 time)
-{
- m_time = time;
- emit timeChanged();
-}
-void WonkoVersion::setRequires(const QVector<WonkoReference> &requires)
-{
- m_requires = requires;
- emit requiresChanged();
-}
-void WonkoVersion::setData(const VersionFilePtr &data)
-{
- m_data = data;
-}
diff --git a/libraries/logic/wonko/WonkoVersion.h b/libraries/logic/wonko/WonkoVersion.h
deleted file mode 100644
index a1de4d9b..00000000
--- a/libraries/logic/wonko/WonkoVersion.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BaseVersion.h"
-#include "BaseWonkoEntity.h"
-
-#include <QVector>
-#include <QStringList>
-#include <QJsonObject>
-#include <memory>
-
-#include "minecraft/VersionFile.h"
-#include "WonkoReference.h"
-
-#include "multimc_logic_export.h"
-
-using WonkoVersionPtr = std::shared_ptr<class WonkoVersion>;
-
-class MULTIMC_LOGIC_EXPORT WonkoVersion : public QObject, public BaseVersion, public BaseWonkoEntity
-{
- Q_OBJECT
- Q_PROPERTY(QString uid READ uid CONSTANT)
- Q_PROPERTY(QString version READ version CONSTANT)
- Q_PROPERTY(QString type READ type NOTIFY typeChanged)
- Q_PROPERTY(QDateTime time READ time NOTIFY timeChanged)
- Q_PROPERTY(QVector<WonkoReference> requires READ requires NOTIFY requiresChanged)
-public:
- explicit WonkoVersion(const QString &uid, const QString &version);
-
- QString descriptor() override;
- QString name() override;
- QString typeString() const override;
-
- QString uid() const { return m_uid; }
- QString version() const { return m_version; }
- QString type() const { return m_type; }
- QDateTime time() const;
- qint64 rawTime() const { return m_time; }
- QVector<WonkoReference> requires() const { return m_requires; }
- VersionFilePtr data() const { return m_data; }
-
- std::unique_ptr<Task> remoteUpdateTask() override;
- std::unique_ptr<Task> localUpdateTask() override;
- void merge(const std::shared_ptr<BaseWonkoEntity> &other) override;
-
- QString localFilename() const override;
- QJsonObject serialized() const override;
-
-public: // for usage by format parsers only
- void setType(const QString &type);
- void setTime(const qint64 time);
- void setRequires(const QVector<WonkoReference> &requires);
- void setData(const VersionFilePtr &data);
-
-signals:
- void typeChanged();
- void timeChanged();
- void requiresChanged();
-
-private:
- QString m_uid;
- QString m_version;
- QString m_type;
- qint64 m_time;
- QVector<WonkoReference> m_requires;
- VersionFilePtr m_data;
-};
-
-Q_DECLARE_METATYPE(WonkoVersionPtr)
diff --git a/libraries/logic/wonko/WonkoVersionList.cpp b/libraries/logic/wonko/WonkoVersionList.cpp
deleted file mode 100644
index e9d79327..00000000
--- a/libraries/logic/wonko/WonkoVersionList.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Copyright 2015 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 "WonkoVersionList.h"
-
-#include <QDateTime>
-
-#include "WonkoVersion.h"
-#include "tasks/BaseWonkoEntityRemoteLoadTask.h"
-#include "tasks/BaseWonkoEntityLocalLoadTask.h"
-#include "format/WonkoFormat.h"
-#include "WonkoReference.h"
-
-class WVLLoadTask : public Task
-{
- Q_OBJECT
-public:
- explicit WVLLoadTask(WonkoVersionList *list, QObject *parent = nullptr)
- : Task(parent), m_list(list)
- {
- }
-
- bool canAbort() const override
- {
- return !m_currentTask || m_currentTask->canAbort();
- }
- bool abort() override
- {
- return m_currentTask->abort();
- }
-
-private:
- void executeTask() override
- {
- if (!m_list->isLocalLoaded())
- {
- m_currentTask = m_list->localUpdateTask();
- connect(m_currentTask.get(), &Task::succeeded, this, &WVLLoadTask::next);
- }
- else
- {
- m_currentTask = m_list->remoteUpdateTask();
- connect(m_currentTask.get(), &Task::succeeded, this, &WVLLoadTask::emitSucceeded);
- }
- connect(m_currentTask.get(), &Task::status, this, &WVLLoadTask::setStatus);
- connect(m_currentTask.get(), &Task::progress, this, &WVLLoadTask::setProgress);
- connect(m_currentTask.get(), &Task::failed, this, &WVLLoadTask::emitFailed);
- m_currentTask->start();
- }
-
- void next()
- {
- m_currentTask = m_list->remoteUpdateTask();
- connect(m_currentTask.get(), &Task::status, this, &WVLLoadTask::setStatus);
- connect(m_currentTask.get(), &Task::progress, this, &WVLLoadTask::setProgress);
- connect(m_currentTask.get(), &Task::succeeded, this, &WVLLoadTask::emitSucceeded);
- m_currentTask->start();
- }
-
- WonkoVersionList *m_list;
- std::unique_ptr<Task> m_currentTask;
-};
-
-WonkoVersionList::WonkoVersionList(const QString &uid, QObject *parent)
- : BaseVersionList(parent), m_uid(uid)
-{
- setObjectName("Wonko version list: " + uid);
-}
-
-Task *WonkoVersionList::getLoadTask()
-{
- return new WVLLoadTask(this);
-}
-
-bool WonkoVersionList::isLoaded()
-{
- return isLocalLoaded() && isRemoteLoaded();
-}
-
-const BaseVersionPtr WonkoVersionList::at(int i) const
-{
- return m_versions.at(i);
-}
-int WonkoVersionList::count() const
-{
- return m_versions.size();
-}
-
-void WonkoVersionList::sortVersions()
-{
- beginResetModel();
- std::sort(m_versions.begin(), m_versions.end(), [](const WonkoVersionPtr &a, const WonkoVersionPtr &b)
- {
- return *a.get() < *b.get();
- });
- endResetModel();
-}
-
-QVariant WonkoVersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid())
- {
- return QVariant();
- }
-
- WonkoVersionPtr version = m_versions.at(index.row());
-
- switch (role)
- {
- case VersionPointerRole: return QVariant::fromValue(std::dynamic_pointer_cast<BaseVersion>(version));
- case VersionRole:
- case VersionIdRole:
- return version->version();
- case ParentGameVersionRole:
- {
- const auto end = version->requires().end();
- const auto it = std::find_if(version->requires().begin(), end,
- [](const WonkoReference &ref) { return ref.uid() == "net.minecraft"; });
- if (it != end)
- {
- return (*it).version();
- }
- return QVariant();
- }
- case TypeRole: return version->type();
-
- case UidRole: return version->uid();
- case TimeRole: return version->time();
- case RequiresRole: return QVariant::fromValue(version->requires());
- case SortRole: return version->rawTime();
- case WonkoVersionPtrRole: return QVariant::fromValue(version);
- case RecommendedRole: return version == getRecommended();
- case LatestRole: return version == getLatestStable();
- default: return QVariant();
- }
-}
-
-BaseVersionList::RoleList WonkoVersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentGameVersionRole,
- TypeRole, UidRole, TimeRole, RequiresRole, SortRole,
- RecommendedRole, LatestRole, WonkoVersionPtrRole};
-}
-
-QHash<int, QByteArray> WonkoVersionList::roleNames() const
-{
- QHash<int, QByteArray> roles = BaseVersionList::roleNames();
- roles.insert(UidRole, "uid");
- roles.insert(TimeRole, "time");
- roles.insert(SortRole, "sort");
- roles.insert(RequiresRole, "requires");
- return roles;
-}
-
-std::unique_ptr<Task> WonkoVersionList::remoteUpdateTask()
-{
- return std::unique_ptr<WonkoVersionListRemoteLoadTask>(new WonkoVersionListRemoteLoadTask(this, this));
-}
-std::unique_ptr<Task> WonkoVersionList::localUpdateTask()
-{
- return std::unique_ptr<WonkoVersionListLocalLoadTask>(new WonkoVersionListLocalLoadTask(this, this));
-}
-
-QString WonkoVersionList::localFilename() const
-{
- return m_uid + ".json";
-}
-QJsonObject WonkoVersionList::serialized() const
-{
- return WonkoFormat::serializeVersionList(this);
-}
-
-QString WonkoVersionList::humanReadable() const
-{
- return m_name.isEmpty() ? m_uid : m_name;
-}
-
-bool WonkoVersionList::hasVersion(const QString &version) const
-{
- return m_lookup.contains(version);
-}
-WonkoVersionPtr WonkoVersionList::getVersion(const QString &version) const
-{
- return m_lookup.value(version);
-}
-
-void WonkoVersionList::setName(const QString &name)
-{
- m_name = name;
- emit nameChanged(name);
-}
-void WonkoVersionList::setVersions(const QVector<WonkoVersionPtr> &versions)
-{
- beginResetModel();
- m_versions = versions;
- std::sort(m_versions.begin(), m_versions.end(), [](const WonkoVersionPtr &a, const WonkoVersionPtr &b)
- {
- return a->rawTime() > b->rawTime();
- });
- for (int i = 0; i < m_versions.size(); ++i)
- {
- m_lookup.insert(m_versions.at(i)->version(), m_versions.at(i));
- setupAddedVersion(i, m_versions.at(i));
- }
-
- m_latest = m_versions.isEmpty() ? nullptr : m_versions.first();
- auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const WonkoVersionPtr &ptr) { return ptr->type() == "release"; });
- m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
- endResetModel();
-}
-
-void WonkoVersionList::merge(const BaseWonkoEntity::Ptr &other)
-{
- const WonkoVersionListPtr list = std::dynamic_pointer_cast<WonkoVersionList>(other);
- if (m_name != list->m_name)
- {
- setName(list->m_name);
- }
-
- if (m_versions.isEmpty())
- {
- setVersions(list->m_versions);
- }
- else
- {
- for (const WonkoVersionPtr &version : list->m_versions)
- {
- if (m_lookup.contains(version->version()))
- {
- m_lookup.value(version->version())->merge(version);
- }
- else
- {
- beginInsertRows(QModelIndex(), m_versions.size(), m_versions.size());
- setupAddedVersion(m_versions.size(), version);
- m_versions.append(version);
- m_lookup.insert(version->uid(), version);
- endInsertRows();
-
- if (!m_latest || version->rawTime() > m_latest->rawTime())
- {
- m_latest = version;
- emit dataChanged(index(0), index(m_versions.size() - 1), QVector<int>() << LatestRole);
- }
- if (!m_recommended || (version->type() == "release" && version->rawTime() > m_recommended->rawTime()))
- {
- m_recommended = version;
- emit dataChanged(index(0), index(m_versions.size() - 1), QVector<int>() << RecommendedRole);
- }
- }
- }
- }
-}
-
-void WonkoVersionList::setupAddedVersion(const int row, const WonkoVersionPtr &version)
-{
- connect(version.get(), &WonkoVersion::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << RequiresRole); });
- connect(version.get(), &WonkoVersion::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TimeRole << SortRole); });
- connect(version.get(), &WonkoVersion::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
-}
-
-BaseVersionPtr WonkoVersionList::getLatestStable() const
-{
- return m_latest;
-}
-BaseVersionPtr WonkoVersionList::getRecommended() const
-{
- return m_recommended;
-}
-
-#include "WonkoVersionList.moc"
diff --git a/libraries/logic/wonko/WonkoVersionList.h b/libraries/logic/wonko/WonkoVersionList.h
deleted file mode 100644
index 8ea35be6..00000000
--- a/libraries/logic/wonko/WonkoVersionList.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BaseVersionList.h"
-#include "BaseWonkoEntity.h"
-#include <memory>
-
-using WonkoVersionPtr = std::shared_ptr<class WonkoVersion>;
-using WonkoVersionListPtr = std::shared_ptr<class WonkoVersionList>;
-
-class MULTIMC_LOGIC_EXPORT WonkoVersionList : public BaseVersionList, public BaseWonkoEntity
-{
- Q_OBJECT
- Q_PROPERTY(QString uid READ uid CONSTANT)
- Q_PROPERTY(QString name READ name NOTIFY nameChanged)
-public:
- explicit WonkoVersionList(const QString &uid, QObject *parent = nullptr);
-
- enum Roles
- {
- UidRole = Qt::UserRole + 100,
- TimeRole,
- RequiresRole,
- WonkoVersionPtrRole
- };
-
- Task *getLoadTask() override;
- bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
- int count() const override;
- void sortVersions() override;
-
- BaseVersionPtr getLatestStable() const override;
- BaseVersionPtr getRecommended() const override;
-
- QVariant data(const QModelIndex &index, int role) const override;
- RoleList providesRoles() const override;
- QHash<int, QByteArray> roleNames() const override;
-
- std::unique_ptr<Task> remoteUpdateTask() override;
- std::unique_ptr<Task> localUpdateTask() override;
-
- QString localFilename() const override;
- QJsonObject serialized() const override;
-
- QString uid() const { return m_uid; }
- QString name() const { return m_name; }
- QString humanReadable() const;
-
- bool hasVersion(const QString &version) const;
- WonkoVersionPtr getVersion(const QString &version) const;
-
- QVector<WonkoVersionPtr> versions() const { return m_versions; }
-
-public: // for usage only by parsers
- void setName(const QString &name);
- void setVersions(const QVector<WonkoVersionPtr> &versions);
- void merge(const BaseWonkoEntity::Ptr &other);
-
-signals:
- void nameChanged(const QString &name);
-
-protected slots:
- void updateListData(QList<BaseVersionPtr> versions) override {}
-
-private:
- QVector<WonkoVersionPtr> m_versions;
- QHash<QString, WonkoVersionPtr> m_lookup;
- QString m_uid;
- QString m_name;
-
- WonkoVersionPtr m_recommended;
- WonkoVersionPtr m_latest;
-
- void setupAddedVersion(const int row, const WonkoVersionPtr &version);
-};
-
-Q_DECLARE_METATYPE(WonkoVersionListPtr)
diff --git a/libraries/logic/wonko/format/WonkoFormat.cpp b/libraries/logic/wonko/format/WonkoFormat.cpp
deleted file mode 100644
index 11192cbe..00000000
--- a/libraries/logic/wonko/format/WonkoFormat.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright 2015 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 "WonkoFormat.h"
-
-#include "WonkoFormatV1.h"
-
-#include "wonko/WonkoIndex.h"
-#include "wonko/WonkoVersion.h"
-#include "wonko/WonkoVersionList.h"
-
-static int formatVersion(const QJsonObject &obj)
-{
- if (!obj.contains("formatVersion")) {
- throw WonkoParseException(QObject::tr("Missing required field: 'formatVersion'"));
- }
- if (!obj.value("formatVersion").isDouble()) {
- throw WonkoParseException(QObject::tr("Required field has invalid type: 'formatVersion'"));
- }
- return obj.value("formatVersion").toInt();
-}
-
-void WonkoFormat::parseIndex(const QJsonObject &obj, WonkoIndex *ptr)
-{
- const int version = formatVersion(obj);
- switch (version) {
- case 1:
- ptr->merge(WonkoFormatV1().parseIndexInternal(obj));
- break;
- default:
- throw WonkoParseException(QObject::tr("Unknown formatVersion: %1").arg(version));
- }
-}
-void WonkoFormat::parseVersion(const QJsonObject &obj, WonkoVersion *ptr)
-{
- const int version = formatVersion(obj);
- switch (version) {
- case 1:
- ptr->merge(WonkoFormatV1().parseVersionInternal(obj));
- break;
- default:
- throw WonkoParseException(QObject::tr("Unknown formatVersion: %1").arg(version));
- }
-}
-void WonkoFormat::parseVersionList(const QJsonObject &obj, WonkoVersionList *ptr)
-{
- const int version = formatVersion(obj);
- switch (version) {
- case 10:
- ptr->merge(WonkoFormatV1().parseVersionListInternal(obj));
- break;
- default:
- throw WonkoParseException(QObject::tr("Unknown formatVersion: %1").arg(version));
- }
-}
-
-QJsonObject WonkoFormat::serializeIndex(const WonkoIndex *ptr)
-{
- return WonkoFormatV1().serializeIndexInternal(ptr);
-}
-QJsonObject WonkoFormat::serializeVersion(const WonkoVersion *ptr)
-{
- return WonkoFormatV1().serializeVersionInternal(ptr);
-}
-QJsonObject WonkoFormat::serializeVersionList(const WonkoVersionList *ptr)
-{
- return WonkoFormatV1().serializeVersionListInternal(ptr);
-}
diff --git a/libraries/logic/wonko/format/WonkoFormat.h b/libraries/logic/wonko/format/WonkoFormat.h
deleted file mode 100644
index 450d6ccc..00000000
--- a/libraries/logic/wonko/format/WonkoFormat.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QJsonObject>
-#include <memory>
-
-#include "Exception.h"
-#include "wonko/BaseWonkoEntity.h"
-
-class WonkoIndex;
-class WonkoVersion;
-class WonkoVersionList;
-
-class WonkoParseException : public Exception
-{
-public:
- using Exception::Exception;
-};
-
-class WonkoFormat
-{
-public:
- virtual ~WonkoFormat() {}
-
- static void parseIndex(const QJsonObject &obj, WonkoIndex *ptr);
- static void parseVersion(const QJsonObject &obj, WonkoVersion *ptr);
- static void parseVersionList(const QJsonObject &obj, WonkoVersionList *ptr);
-
- static QJsonObject serializeIndex(const WonkoIndex *ptr);
- static QJsonObject serializeVersion(const WonkoVersion *ptr);
- static QJsonObject serializeVersionList(const WonkoVersionList *ptr);
-
-protected:
- virtual BaseWonkoEntity::Ptr parseIndexInternal(const QJsonObject &obj) const = 0;
- virtual BaseWonkoEntity::Ptr parseVersionInternal(const QJsonObject &obj) const = 0;
- virtual BaseWonkoEntity::Ptr parseVersionListInternal(const QJsonObject &obj) const = 0;
- virtual QJsonObject serializeIndexInternal(const WonkoIndex *ptr) const = 0;
- virtual QJsonObject serializeVersionInternal(const WonkoVersion *ptr) const = 0;
- virtual QJsonObject serializeVersionListInternal(const WonkoVersionList *ptr) const = 0;
-};
diff --git a/libraries/logic/wonko/format/WonkoFormatV1.cpp b/libraries/logic/wonko/format/WonkoFormatV1.cpp
deleted file mode 100644
index 363eebfb..00000000
--- a/libraries/logic/wonko/format/WonkoFormatV1.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/* Copyright 2015 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 "WonkoFormatV1.h"
-#include <minecraft/onesix/OneSixVersionFormat.h>
-
-#include "Json.h"
-
-#include "wonko/WonkoIndex.h"
-#include "wonko/WonkoVersion.h"
-#include "wonko/WonkoVersionList.h"
-#include "Env.h"
-
-using namespace Json;
-
-static WonkoVersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
-{
- const QVector<QJsonObject> requiresRaw = obj.contains("requires") ? requireIsArrayOf<QJsonObject>(obj, "requires") : QVector<QJsonObject>();
- QVector<WonkoReference> requires;
- requires.reserve(requiresRaw.size());
- std::transform(requiresRaw.begin(), requiresRaw.end(), std::back_inserter(requires), [](const QJsonObject &rObj)
- {
- WonkoReference ref(requireString(rObj, "uid"));
- ref.setVersion(ensureString(rObj, "version", QString()));
- return ref;
- });
-
- WonkoVersionPtr version = std::make_shared<WonkoVersion>(uid, requireString(obj, "version"));
- if (obj.value("time").isString())
- {
- version->setTime(QDateTime::fromString(requireString(obj, "time"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
- }
- else
- {
- version->setTime(requireInteger(obj, "time"));
- }
- version->setType(ensureString(obj, "type", QString()));
- version->setRequires(requires);
- return version;
-}
-static void serializeCommonVersion(const WonkoVersion *version, QJsonObject &obj)
-{
- QJsonArray requires;
- for (const WonkoReference &ref : version->requires())
- {
- if (ref.version().isEmpty())
- {
- requires.append(QJsonObject({{"uid", ref.uid()}}));
- }
- else
- {
- requires.append(QJsonObject({
- {"uid", ref.uid()},
- {"version", ref.version()}
- }));
- }
- }
-
- obj.insert("version", version->version());
- obj.insert("type", version->type());
- obj.insert("time", version->time().toString(Qt::ISODate));
- obj.insert("requires", requires);
-}
-
-BaseWonkoEntity::Ptr WonkoFormatV1::parseIndexInternal(const QJsonObject &obj) const
-{
- const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "index");
- QVector<WonkoVersionListPtr> lists;
- lists.reserve(objects.size());
- std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
- {
- WonkoVersionListPtr list = std::make_shared<WonkoVersionList>(requireString(obj, "uid"));
- list->setName(ensureString(obj, "name", QString()));
- return list;
- });
- return std::make_shared<WonkoIndex>(lists);
-}
-BaseWonkoEntity::Ptr WonkoFormatV1::parseVersionInternal(const QJsonObject &obj) const
-{
- WonkoVersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
-
- version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
- QString("%1/%2.json").arg(version->uid(), version->version()),
- obj.contains("order")));
- return version;
-}
-BaseWonkoEntity::Ptr WonkoFormatV1::parseVersionListInternal(const QJsonObject &obj) const
-{
- const QString uid = requireString(obj, "uid");
-
- const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
- QVector<WonkoVersionPtr> versions;
- versions.reserve(versionsRaw.size());
- std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [this, uid](const QJsonObject &vObj)
- { return parseCommonVersion(uid, vObj); });
-
- WonkoVersionListPtr list = std::make_shared<WonkoVersionList>(uid);
- list->setName(ensureString(obj, "name", QString()));
- list->setVersions(versions);
- return list;
-}
-
-QJsonObject WonkoFormatV1::serializeIndexInternal(const WonkoIndex *ptr) const
-{
- QJsonArray index;
- for (const WonkoVersionListPtr &list : ptr->lists())
- {
- index.append(QJsonObject({
- {"uid", list->uid()},
- {"name", list->name()}
- }));
- }
- return QJsonObject({
- {"formatVersion", 1},
- {"index", index}
- });
-}
-QJsonObject WonkoFormatV1::serializeVersionInternal(const WonkoVersion *ptr) const
-{
- QJsonObject obj = OneSixVersionFormat::versionFileToJson(ptr->data(), true).object();
- serializeCommonVersion(ptr, obj);
- obj.insert("formatVersion", 1);
- obj.insert("uid", ptr->uid());
- // TODO: the name should be looked up in the UI based on the uid
- obj.insert("name", ENV.wonkoIndex()->getListGuaranteed(ptr->uid())->name());
-
- return obj;
-}
-QJsonObject WonkoFormatV1::serializeVersionListInternal(const WonkoVersionList *ptr) const
-{
- QJsonArray versions;
- for (const WonkoVersionPtr &version : ptr->versions())
- {
- QJsonObject obj;
- serializeCommonVersion(version.get(), obj);
- versions.append(obj);
- }
- return QJsonObject({
- {"formatVersion", 10},
- {"uid", ptr->uid()},
- {"name", ptr->name().isNull() ? QJsonValue() : ptr->name()},
- {"versions", versions}
- });
-}
diff --git a/libraries/logic/wonko/format/WonkoFormatV1.h b/libraries/logic/wonko/format/WonkoFormatV1.h
deleted file mode 100644
index 92759804..00000000
--- a/libraries/logic/wonko/format/WonkoFormatV1.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "WonkoFormat.h"
-
-class WonkoFormatV1 : public WonkoFormat
-{
-public:
- BaseWonkoEntity::Ptr parseIndexInternal(const QJsonObject &obj) const override;
- BaseWonkoEntity::Ptr parseVersionInternal(const QJsonObject &obj) const override;
- BaseWonkoEntity::Ptr parseVersionListInternal(const QJsonObject &obj) const override;
-
- QJsonObject serializeIndexInternal(const WonkoIndex *ptr) const override;
- QJsonObject serializeVersionInternal(const WonkoVersion *ptr) const override;
- QJsonObject serializeVersionListInternal(const WonkoVersionList *ptr) const override;
-};
diff --git a/libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.cpp b/libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.cpp
deleted file mode 100644
index b54c592f..00000000
--- a/libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright 2015 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 "BaseWonkoEntityLocalLoadTask.h"
-
-#include <QFile>
-
-#include "wonko/format/WonkoFormat.h"
-#include "wonko/WonkoUtil.h"
-#include "wonko/WonkoIndex.h"
-#include "wonko/WonkoVersion.h"
-#include "wonko/WonkoVersionList.h"
-#include "Env.h"
-#include "Json.h"
-
-BaseWonkoEntityLocalLoadTask::BaseWonkoEntityLocalLoadTask(BaseWonkoEntity *entity, QObject *parent)
- : Task(parent), m_entity(entity)
-{
-}
-
-void BaseWonkoEntityLocalLoadTask::executeTask()
-{
- const QString fname = Wonko::localWonkoDir().absoluteFilePath(filename());
- if (!QFile::exists(fname))
- {
- emitFailed(tr("File doesn't exist"));
- return;
- }
-
- setStatus(tr("Reading %1...").arg(name()));
- setProgress(0, 0);
-
- try
- {
- parse(Json::requireObject(Json::requireDocument(fname, name()), name()));
- m_entity->notifyLocalLoadComplete();
- emitSucceeded();
- }
- catch (Exception &e)
- {
- emitFailed(tr("Unable to parse file %1: %2").arg(fname, e.cause()));
- }
-}
-
-// WONKO INDEX //
-WonkoIndexLocalLoadTask::WonkoIndexLocalLoadTask(WonkoIndex *index, QObject *parent)
- : BaseWonkoEntityLocalLoadTask(index, parent)
-{
-}
-QString WonkoIndexLocalLoadTask::filename() const
-{
- return "index.json";
-}
-QString WonkoIndexLocalLoadTask::name() const
-{
- return tr("Wonko Index");
-}
-void WonkoIndexLocalLoadTask::parse(const QJsonObject &obj) const
-{
- WonkoFormat::parseIndex(obj, dynamic_cast<WonkoIndex *>(entity()));
-}
-
-// WONKO VERSION LIST //
-WonkoVersionListLocalLoadTask::WonkoVersionListLocalLoadTask(WonkoVersionList *list, QObject *parent)
- : BaseWonkoEntityLocalLoadTask(list, parent)
-{
-}
-QString WonkoVersionListLocalLoadTask::filename() const
-{
- return list()->uid() + ".json";
-}
-QString WonkoVersionListLocalLoadTask::name() const
-{
- return tr("Wonko Version List for %1").arg(list()->humanReadable());
-}
-void WonkoVersionListLocalLoadTask::parse(const QJsonObject &obj) const
-{
- WonkoFormat::parseVersionList(obj, list());
-}
-WonkoVersionList *WonkoVersionListLocalLoadTask::list() const
-{
- return dynamic_cast<WonkoVersionList *>(entity());
-}
-
-// WONKO VERSION //
-WonkoVersionLocalLoadTask::WonkoVersionLocalLoadTask(WonkoVersion *version, QObject *parent)
- : BaseWonkoEntityLocalLoadTask(version, parent)
-{
-}
-QString WonkoVersionLocalLoadTask::filename() const
-{
- return version()->uid() + "/" + version()->version() + ".json";
-}
-QString WonkoVersionLocalLoadTask::name() const
-{
- return tr("Wonko Version for %1").arg(version()->name());
-}
-void WonkoVersionLocalLoadTask::parse(const QJsonObject &obj) const
-{
- WonkoFormat::parseVersion(obj, version());
-}
-WonkoVersion *WonkoVersionLocalLoadTask::version() const
-{
- return dynamic_cast<WonkoVersion *>(entity());
-}
diff --git a/libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.h b/libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.h
deleted file mode 100644
index 2affa17f..00000000
--- a/libraries/logic/wonko/tasks/BaseWonkoEntityLocalLoadTask.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "tasks/Task.h"
-#include <memory>
-
-class BaseWonkoEntity;
-class WonkoIndex;
-class WonkoVersionList;
-class WonkoVersion;
-
-class BaseWonkoEntityLocalLoadTask : public Task
-{
- Q_OBJECT
-public:
- explicit BaseWonkoEntityLocalLoadTask(BaseWonkoEntity *entity, QObject *parent = nullptr);
-
-protected:
- virtual QString filename() const = 0;
- virtual QString name() const = 0;
- virtual void parse(const QJsonObject &obj) const = 0;
-
- BaseWonkoEntity *entity() const { return m_entity; }
-
-private:
- void executeTask() override;
-
- BaseWonkoEntity *m_entity;
-};
-
-class WonkoIndexLocalLoadTask : public BaseWonkoEntityLocalLoadTask
-{
- Q_OBJECT
-public:
- explicit WonkoIndexLocalLoadTask(WonkoIndex *index, QObject *parent = nullptr);
-
-private:
- QString filename() const override;
- QString name() const override;
- void parse(const QJsonObject &obj) const override;
-};
-class WonkoVersionListLocalLoadTask : public BaseWonkoEntityLocalLoadTask
-{
- Q_OBJECT
-public:
- explicit WonkoVersionListLocalLoadTask(WonkoVersionList *list, QObject *parent = nullptr);
-
-private:
- QString filename() const override;
- QString name() const override;
- void parse(const QJsonObject &obj) const override;
-
- WonkoVersionList *list() const;
-};
-class WonkoVersionLocalLoadTask : public BaseWonkoEntityLocalLoadTask
-{
- Q_OBJECT
-public:
- explicit WonkoVersionLocalLoadTask(WonkoVersion *version, QObject *parent = nullptr);
-
-private:
- QString filename() const override;
- QString name() const override;
- void parse(const QJsonObject &obj) const override;
-
- WonkoVersion *version() const;
-};
diff --git a/libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.cpp b/libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.cpp
deleted file mode 100644
index 727ec89d..00000000
--- a/libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright 2015 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 "BaseWonkoEntityRemoteLoadTask.h"
-
-#include "net/CacheDownload.h"
-#include "net/HttpMetaCache.h"
-#include "net/NetJob.h"
-#include "wonko/format/WonkoFormat.h"
-#include "wonko/WonkoUtil.h"
-#include "wonko/WonkoIndex.h"
-#include "wonko/WonkoVersion.h"
-#include "wonko/WonkoVersionList.h"
-#include "Env.h"
-#include "Json.h"
-
-BaseWonkoEntityRemoteLoadTask::BaseWonkoEntityRemoteLoadTask(BaseWonkoEntity *entity, QObject *parent)
- : Task(parent), m_entity(entity)
-{
-}
-
-void BaseWonkoEntityRemoteLoadTask::executeTask()
-{
- NetJob *job = new NetJob(name());
-
- auto entry = ENV.metacache()->resolveEntry("wonko", url().toString());
- entry->setStale(true);
- m_dl = CacheDownload::make(url(), entry);
- job->addNetAction(m_dl);
- connect(job, &NetJob::failed, this, &BaseWonkoEntityRemoteLoadTask::emitFailed);
- connect(job, &NetJob::succeeded, this, &BaseWonkoEntityRemoteLoadTask::networkFinished);
- connect(job, &NetJob::status, this, &BaseWonkoEntityRemoteLoadTask::setStatus);
- connect(job, &NetJob::progress, this, &BaseWonkoEntityRemoteLoadTask::setProgress);
- job->start();
-}
-
-void BaseWonkoEntityRemoteLoadTask::networkFinished()
-{
- setStatus(tr("Parsing..."));
- setProgress(0, 0);
-
- try
- {
- parse(Json::requireObject(Json::requireDocument(m_dl->getTargetFilepath(), name()), name()));
- m_entity->notifyRemoteLoadComplete();
- emitSucceeded();
- }
- catch (Exception &e)
- {
- emitFailed(tr("Unable to parse response: %1").arg(e.cause()));
- }
-}
-
-// WONKO INDEX //
-WonkoIndexRemoteLoadTask::WonkoIndexRemoteLoadTask(WonkoIndex *index, QObject *parent)
- : BaseWonkoEntityRemoteLoadTask(index, parent)
-{
-}
-QUrl WonkoIndexRemoteLoadTask::url() const
-{
- return Wonko::indexUrl();
-}
-QString WonkoIndexRemoteLoadTask::name() const
-{
- return tr("Wonko Index");
-}
-void WonkoIndexRemoteLoadTask::parse(const QJsonObject &obj) const
-{
- WonkoFormat::parseIndex(obj, dynamic_cast<WonkoIndex *>(entity()));
-}
-
-// WONKO VERSION LIST //
-WonkoVersionListRemoteLoadTask::WonkoVersionListRemoteLoadTask(WonkoVersionList *list, QObject *parent)
- : BaseWonkoEntityRemoteLoadTask(list, parent)
-{
-}
-QUrl WonkoVersionListRemoteLoadTask::url() const
-{
- return Wonko::versionListUrl(list()->uid());
-}
-QString WonkoVersionListRemoteLoadTask::name() const
-{
- return tr("Wonko Version List for %1").arg(list()->humanReadable());
-}
-void WonkoVersionListRemoteLoadTask::parse(const QJsonObject &obj) const
-{
- WonkoFormat::parseVersionList(obj, list());
-}
-WonkoVersionList *WonkoVersionListRemoteLoadTask::list() const
-{
- return dynamic_cast<WonkoVersionList *>(entity());
-}
-
-// WONKO VERSION //
-WonkoVersionRemoteLoadTask::WonkoVersionRemoteLoadTask(WonkoVersion *version, QObject *parent)
- : BaseWonkoEntityRemoteLoadTask(version, parent)
-{
-}
-QUrl WonkoVersionRemoteLoadTask::url() const
-{
- return Wonko::versionUrl(version()->uid(), version()->version());
-}
-QString WonkoVersionRemoteLoadTask::name() const
-{
- return tr("Wonko Version for %1").arg(version()->name());
-}
-void WonkoVersionRemoteLoadTask::parse(const QJsonObject &obj) const
-{
- WonkoFormat::parseVersion(obj, version());
-}
-WonkoVersion *WonkoVersionRemoteLoadTask::version() const
-{
- return dynamic_cast<WonkoVersion *>(entity());
-}
diff --git a/libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.h b/libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.h
deleted file mode 100644
index 91ed6af0..00000000
--- a/libraries/logic/wonko/tasks/BaseWonkoEntityRemoteLoadTask.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright 2015 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "tasks/Task.h"
-#include <memory>
-
-class BaseWonkoEntity;
-class WonkoIndex;
-class WonkoVersionList;
-class WonkoVersion;
-
-class BaseWonkoEntityRemoteLoadTask : public Task
-{
- Q_OBJECT
-public:
- explicit BaseWonkoEntityRemoteLoadTask(BaseWonkoEntity *entity, QObject *parent = nullptr);
-
-protected:
- virtual QUrl url() const = 0;
- virtual QString name() const = 0;
- virtual void parse(const QJsonObject &obj) const = 0;
-
- BaseWonkoEntity *entity() const { return m_entity; }
-
-private slots:
- void networkFinished();
-
-private:
- void executeTask() override;
-
- BaseWonkoEntity *m_entity;
- std::shared_ptr<class CacheDownload> m_dl;
-};
-
-class WonkoIndexRemoteLoadTask : public BaseWonkoEntityRemoteLoadTask
-{
- Q_OBJECT
-public:
- explicit WonkoIndexRemoteLoadTask(WonkoIndex *index, QObject *parent = nullptr);
-
-private:
- QUrl url() const override;
- QString name() const override;
- void parse(const QJsonObject &obj) const override;
-};
-class WonkoVersionListRemoteLoadTask : public BaseWonkoEntityRemoteLoadTask
-{
- Q_OBJECT
-public:
- explicit WonkoVersionListRemoteLoadTask(WonkoVersionList *list, QObject *parent = nullptr);
-
-private:
- QUrl url() const override;
- QString name() const override;
- void parse(const QJsonObject &obj) const override;
-
- WonkoVersionList *list() const;
-};
-class WonkoVersionRemoteLoadTask : public BaseWonkoEntityRemoteLoadTask
-{
- Q_OBJECT
-public:
- explicit WonkoVersionRemoteLoadTask(WonkoVersion *version, QObject *parent = nullptr);
-
-private:
- QUrl url() const override;
- QString name() const override;
- void parse(const QJsonObject &obj) const override;
-
- WonkoVersion *version() const;
-};