1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-FileCopyrightText: 2026 Project Tick
// SPDX-FileContributor: Project Tick Team
/*
* ProjT Launcher - Minecraft Launcher
* Copyright (C) 2026 Project Tick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
#include <QDateTime>
#include <QJsonDocument>
#include <QList>
#include <memory>
#include <optional>
#include <variant>
#include "ProblemProvider.h"
#include "QObjectPtr.h"
#include "meta/JsonFormat.hpp"
#include "modplatform/ModIndex.h"
class PackProfile;
class LaunchProfile;
namespace projt::meta
{
class MetaVersion;
class MetaVersionList;
} // namespace projt::meta
class VersionFile;
struct UpdateActionChangeVersion
{
/// version to change to
QString targetVersion;
};
struct UpdateActionLatestRecommendedCompatible
{
/// Parent uid
QString parentUid;
QString parentName;
/// Parent version
QString version;
///
};
struct UpdateActionRemove
{};
struct UpdateActionImportantChanged
{
QString oldVersion;
};
using UpdateActionNone = std::monostate;
using UpdateAction = std::variant<UpdateActionNone,
UpdateActionChangeVersion,
UpdateActionLatestRecommendedCompatible,
UpdateActionRemove,
UpdateActionImportantChanged>;
struct ModloaderMapEntry
{
ModPlatform::ModLoaderType type;
QStringList knownConflictingComponents;
};
class Component : public QObject, public ProblemProvider
{
Q_OBJECT
public:
Component(PackProfile* parent, const QString& uid);
// DEPRECATED: remove these constructors?
Component(PackProfile* parent, const QString& uid, std::shared_ptr<VersionFile> file);
virtual ~Component()
{}
static const QMap<QString, ModloaderMapEntry> KNOWN_MODLOADERS;
void applyTo(LaunchProfile* profile);
bool isEnabled();
bool setEnabled(bool state);
bool canBeDisabled();
bool isMoveable();
bool isCustomizable();
bool isRevertible();
bool isRemovable();
bool isCustom();
bool isVersionChangeable(bool wait = true);
bool isKnownModloader();
QStringList knownConflictingComponents();
// DEPRECATED: explicit numeric order values, used for loading old non-component config.
// NOTE: Kept for legacy migration support.
void setOrder(int order);
int getOrder();
QString getID();
QString getName();
QString getVersion();
std::shared_ptr<projt::meta::MetaVersion> getMeta();
QDateTime getReleaseDateTime();
QString getFilename();
std::shared_ptr<class VersionFile> getVersionFile() const;
std::shared_ptr<projt::meta::MetaVersionList> getVersionList() const;
void setImportant(bool state);
const QList<PatchProblem> getProblems() const override;
ProblemSeverity getProblemSeverity() const override;
void addComponentProblem(ProblemSeverity severity, const QString& description);
void resetComponentProblems();
void setVersion(const QString& version);
bool customize();
bool revert();
void updateCachedData();
void waitLoadMeta();
void setUpdateAction(const UpdateAction& action);
void clearUpdateAction();
UpdateAction getUpdateAction();
signals:
void dataChanged();
public: /* data */
PackProfile* m_parent;
// BEGIN: persistent component list properties
/// ID of the component
QString m_uid;
/// version of the component - when there's a custom json override, this is also the version the component reverts to
QString m_version;
/// if true, this has been added automatically to satisfy dependencies and may be automatically removed
bool m_dependencyOnly = false;
/// if true, the component is either the main component of the instance, or otherwise important and cannot be removed.
bool m_important = false;
/// if true, the component is disabled
bool m_disabled = false;
/// cached name for display purposes, taken from the version file (meta or local override)
QString m_cachedName;
/// cached version for display AND other purposes, taken from the version file (meta or local override)
QString m_cachedVersion;
/// cached set of requirements, taken from the version file (meta or local override)
projt::meta::DependencySet m_cachedRequires;
projt::meta::DependencySet m_cachedConflicts;
/// if true, the component is volatile and may be automatically removed when no longer needed
bool m_cachedVolatile = false;
// END: persistent component list properties
// DEPRECATED: explicit numeric order values, used for loading old non-component config.
// NOTE: Kept for legacy migration support.
bool m_orderOverride = false;
int m_order = 0;
// load state
std::shared_ptr<projt::meta::MetaVersion> m_metaVersion;
std::shared_ptr<VersionFile> m_file;
bool m_loaded = false;
private:
QList<PatchProblem> m_componentProblems;
ProblemSeverity m_componentProblemSeverity = ProblemSeverity::None;
UpdateAction m_updateAction = UpdateAction{ UpdateActionNone{} };
};
using ComponentPtr = shared_qobject_ptr<Component>;
|