add better profile logging properly resolve important dependencies
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
parent
ce280c2d04
commit
a94a081b9c
@ -206,6 +206,11 @@ set(ICONS_SOURCES
|
|||||||
|
|
||||||
# Support for Minecraft instances and launch
|
# Support for Minecraft instances and launch
|
||||||
set(MINECRAFT_SOURCES
|
set(MINECRAFT_SOURCES
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
minecraft/Logging.h
|
||||||
|
minecraft/Logging.cpp
|
||||||
|
|
||||||
# Minecraft support
|
# Minecraft support
|
||||||
minecraft/auth/AccountData.cpp
|
minecraft/auth/AccountData.cpp
|
||||||
minecraft/auth/AccountData.h
|
minecraft/auth/AccountData.h
|
||||||
@ -650,6 +655,22 @@ ecm_qt_declare_logging_category(CORE_SOURCES
|
|||||||
EXPORT "${Launcher_Name}"
|
EXPORT "${Launcher_Name}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ecm_qt_export_logging_category(
|
||||||
|
IDENTIFIER instanceProfileC
|
||||||
|
CATEGORY_NAME "launcher.instance.profile"
|
||||||
|
DEFAULT_SEVERITY Debug
|
||||||
|
DESCRIPTION "Profile actions"
|
||||||
|
EXPORT "${Launcher_Name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_export_logging_category(
|
||||||
|
IDENTIFIER instanceProfileResolveC
|
||||||
|
CATEGORY_NAME "launcher.instance.profile.resolve"
|
||||||
|
DEFAULT_SEVERITY Debug
|
||||||
|
DESCRIPTION "Profile component resolusion actions"
|
||||||
|
EXPORT "${Launcher_Name}"
|
||||||
|
)
|
||||||
|
|
||||||
ecm_qt_export_logging_category(
|
ecm_qt_export_logging_category(
|
||||||
IDENTIFIER taskLogC
|
IDENTIFIER taskLogC
|
||||||
CATEGORY_NAME "launcher.task"
|
CATEGORY_NAME "launcher.task"
|
||||||
@ -662,7 +683,7 @@ ecm_qt_export_logging_category(
|
|||||||
IDENTIFIER taskNetLogC
|
IDENTIFIER taskNetLogC
|
||||||
CATEGORY_NAME "launcher.task.net"
|
CATEGORY_NAME "launcher.task.net"
|
||||||
DEFAULT_SEVERITY Debug
|
DEFAULT_SEVERITY Debug
|
||||||
DESCRIPTION "task network action"
|
DESCRIPTION "Task network action"
|
||||||
EXPORT "${Launcher_Name}"
|
EXPORT "${Launcher_Name}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -670,14 +691,14 @@ ecm_qt_export_logging_category(
|
|||||||
IDENTIFIER taskDownloadLogC
|
IDENTIFIER taskDownloadLogC
|
||||||
CATEGORY_NAME "launcher.task.net.download"
|
CATEGORY_NAME "launcher.task.net.download"
|
||||||
DEFAULT_SEVERITY Debug
|
DEFAULT_SEVERITY Debug
|
||||||
DESCRIPTION "task network download actions"
|
DESCRIPTION "Task network download actions"
|
||||||
EXPORT "${Launcher_Name}"
|
EXPORT "${Launcher_Name}"
|
||||||
)
|
)
|
||||||
ecm_qt_export_logging_category(
|
ecm_qt_export_logging_category(
|
||||||
IDENTIFIER taskUploadLogC
|
IDENTIFIER taskUploadLogC
|
||||||
CATEGORY_NAME "launcher.task.net.upload"
|
CATEGORY_NAME "launcher.task.net.upload"
|
||||||
DEFAULT_SEVERITY Debug
|
DEFAULT_SEVERITY Debug
|
||||||
DESCRIPTION "task network upload actions"
|
DESCRIPTION "Task network upload actions"
|
||||||
EXPORT "${Launcher_Name}"
|
EXPORT "${Launcher_Name}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -287,7 +287,11 @@ Version::Ptr VersionList::getRecommendedForParent(const QString& uid, const QStr
|
|||||||
if (foundExplicit != m_versions.end()) {
|
if (foundExplicit != m_versions.end()) {
|
||||||
return *foundExplicit;
|
return *foundExplicit;
|
||||||
}
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Version::Ptr VersionList::getLatestForParent(const QString& uid, const QString& version)
|
||||||
|
{
|
||||||
Version::Ptr latestCompat = nullptr;
|
Version::Ptr latestCompat = nullptr;
|
||||||
for (auto ver : m_versions) {
|
for (auto ver : m_versions) {
|
||||||
auto& reqs = ver->requiredSet();
|
auto& reqs = ver->requiredSet();
|
||||||
|
@ -44,6 +44,7 @@ class VersionList : public BaseVersionList, public BaseEntity {
|
|||||||
|
|
||||||
BaseVersion::Ptr getRecommended() const override;
|
BaseVersion::Ptr getRecommended() const override;
|
||||||
Version::Ptr getRecommendedForParent(const QString& uid, const QString& version);
|
Version::Ptr getRecommendedForParent(const QString& uid, const QString& version);
|
||||||
|
Version::Ptr getLatestForParent(const QString& uid, const QString& version);
|
||||||
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex& index, int role) const override;
|
QVariant data(const QModelIndex& index, int role) const override;
|
||||||
|
@ -403,6 +403,18 @@ void Component::updateCachedData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Component::waitLoadMeta() {
|
||||||
|
|
||||||
|
if (!m_loaded) {
|
||||||
|
if (!m_metaVersion || !m_metaVersion->isLoaded()) {
|
||||||
|
// wait for the loaded version from meta
|
||||||
|
m_metaVersion = APPLICATION->metadataIndex()->getLoadedVersion(m_uid, m_version);
|
||||||
|
}
|
||||||
|
m_loaded = true;
|
||||||
|
updateCachedData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug d, const Component& comp) {
|
QDebug operator<<(QDebug d, const Component& comp) {
|
||||||
d << "Component(" << comp.m_uid << " : " << comp.m_cachedVersion << ")";
|
d << "Component(" << comp.m_uid << " : " << comp.m_cachedVersion << ")";
|
||||||
return d;
|
return d;
|
||||||
|
@ -64,6 +64,8 @@ class Component : public QObject, public ProblemProvider {
|
|||||||
bool revert();
|
bool revert();
|
||||||
|
|
||||||
void updateCachedData();
|
void updateCachedData();
|
||||||
|
|
||||||
|
void waitLoadMeta();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dataChanged();
|
void dataChanged();
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "cassert"
|
#include "cassert"
|
||||||
#include "meta/Index.h"
|
#include "meta/Index.h"
|
||||||
#include "meta/Version.h"
|
#include "meta/Version.h"
|
||||||
|
#include "minecraft/MinecraftInstance.h"
|
||||||
#include "minecraft/OneSixVersionFormat.h"
|
#include "minecraft/OneSixVersionFormat.h"
|
||||||
#include "minecraft/ProfileUtils.h"
|
#include "minecraft/ProfileUtils.h"
|
||||||
#include "net/Mode.h"
|
#include "net/Mode.h"
|
||||||
@ -15,6 +16,8 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "tasks/Task.h"
|
#include "tasks/Task.h"
|
||||||
|
|
||||||
|
#include "minecraft/Logging.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is responsible for loading the components of a component list AND resolving dependency issues between them
|
* This is responsible for loading the components of a component list AND resolving dependency issues between them
|
||||||
*/
|
*/
|
||||||
@ -36,7 +39,7 @@
|
|||||||
ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent) : Task(parent)
|
ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, PackProfile* list, QObject* parent) : Task(parent)
|
||||||
{
|
{
|
||||||
d.reset(new ComponentUpdateTaskData);
|
d.reset(new ComponentUpdateTaskData);
|
||||||
d->m_list = list;
|
d->m_profile = list;
|
||||||
d->mode = mode;
|
d->mode = mode;
|
||||||
d->netmode = netmode;
|
d->netmode = netmode;
|
||||||
}
|
}
|
||||||
@ -45,7 +48,7 @@ ComponentUpdateTask::~ComponentUpdateTask() {}
|
|||||||
|
|
||||||
void ComponentUpdateTask::executeTask()
|
void ComponentUpdateTask::executeTask()
|
||||||
{
|
{
|
||||||
qDebug() << "Loading components";
|
qCDebug(instanceProfileResolveC) << "Loading components";
|
||||||
loadComponents();
|
loadComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +66,7 @@ LoadResult composeLoadResult(LoadResult a, LoadResult b)
|
|||||||
static LoadResult loadComponent(ComponentPtr component, Task::Ptr& loadTask, Net::Mode netmode)
|
static LoadResult loadComponent(ComponentPtr component, Task::Ptr& loadTask, Net::Mode netmode)
|
||||||
{
|
{
|
||||||
if (component->m_loaded) {
|
if (component->m_loaded) {
|
||||||
qDebug() << component->getName() << "is already loaded";
|
qCDebug(instanceProfileResolveC) << component->getName() << "is already loaded";
|
||||||
return LoadResult::LoadedLocal;
|
return LoadResult::LoadedLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +147,7 @@ void ComponentUpdateTask::loadComponents()
|
|||||||
d->remoteLoadSuccessful = true;
|
d->remoteLoadSuccessful = true;
|
||||||
|
|
||||||
// load all the components OR their lists...
|
// load all the components OR their lists...
|
||||||
for (auto component : d->m_list->d->components) {
|
for (auto component : d->m_profile->d->components) {
|
||||||
Task::Ptr loadTask;
|
Task::Ptr loadTask;
|
||||||
LoadResult singleResult;
|
LoadResult singleResult;
|
||||||
RemoteLoadStatus::Type loadType;
|
RemoteLoadStatus::Type loadType;
|
||||||
@ -175,7 +178,7 @@ void ComponentUpdateTask::loadComponents()
|
|||||||
}
|
}
|
||||||
result = composeLoadResult(result, singleResult);
|
result = composeLoadResult(result, singleResult);
|
||||||
if (loadTask) {
|
if (loadTask) {
|
||||||
qDebug() << "Remote loading is being run for" << component->getName();
|
qCDebug(instanceProfileResolveC) << d->m_profile->d->m_instance->name() << "|" << "Remote loading is being run for" << component->getName();
|
||||||
connect(loadTask.get(), &Task::succeeded, this, [this, taskIndex]() { remoteLoadSucceeded(taskIndex); });
|
connect(loadTask.get(), &Task::succeeded, this, [this, taskIndex]() { remoteLoadSucceeded(taskIndex); });
|
||||||
connect(loadTask.get(), &Task::failed, this, [this, taskIndex](const QString& error) { remoteLoadFailed(taskIndex, error); });
|
connect(loadTask.get(), &Task::failed, this, [this, taskIndex](const QString& error) { remoteLoadFailed(taskIndex, error); });
|
||||||
connect(loadTask.get(), &Task::aborted, this, [this, taskIndex]() { remoteLoadFailed(taskIndex, tr("Aborted")); });
|
connect(loadTask.get(), &Task::aborted, this, [this, taskIndex]() { remoteLoadFailed(taskIndex, tr("Aborted")); });
|
||||||
@ -270,7 +273,7 @@ static bool gatherRequirementsFromComponents(const ComponentContainer& input, Re
|
|||||||
output.erase(componenRequireEx);
|
output.erase(componenRequireEx);
|
||||||
output.insert(result.outcome);
|
output.insert(result.outcome);
|
||||||
} else {
|
} else {
|
||||||
qCritical() << "Conflicting requirements:" << componentRequire.uid << "versions:" << componentRequire.equalsVersion
|
qCCritical(instanceProfileResolveC) << "Conflicting requirements:" << componentRequire.uid << "versions:" << componentRequire.equalsVersion
|
||||||
<< ";" << (*found).equalsVersion;
|
<< ";" << (*found).equalsVersion;
|
||||||
}
|
}
|
||||||
succeeded &= result.ok;
|
succeeded &= result.ok;
|
||||||
@ -353,22 +356,22 @@ static bool getTrivialComponentChanges(const ComponentIndex& index, const Requir
|
|||||||
} while (false);
|
} while (false);
|
||||||
switch (decision) {
|
switch (decision) {
|
||||||
case Decision::Undetermined:
|
case Decision::Undetermined:
|
||||||
qCritical() << "No decision for" << reqStr;
|
qCCritical(instanceProfileResolveC) << "No decision for" << reqStr;
|
||||||
succeeded = false;
|
succeeded = false;
|
||||||
break;
|
break;
|
||||||
case Decision::Met:
|
case Decision::Met:
|
||||||
qDebug() << reqStr << "Is met.";
|
qCDebug(instanceProfileResolveC) << reqStr << "Is met.";
|
||||||
break;
|
break;
|
||||||
case Decision::Missing:
|
case Decision::Missing:
|
||||||
qDebug() << reqStr << "Is missing and should be added at" << req.indexOfFirstDependee;
|
qCDebug(instanceProfileResolveC) << reqStr << "Is missing and should be added at" << req.indexOfFirstDependee;
|
||||||
toAdd.insert(req);
|
toAdd.insert(req);
|
||||||
break;
|
break;
|
||||||
case Decision::VersionNotSame:
|
case Decision::VersionNotSame:
|
||||||
qDebug() << reqStr << "already has different version that can be changed.";
|
qCDebug(instanceProfileResolveC) << reqStr << "already has different version that can be changed.";
|
||||||
toChange.insert(req);
|
toChange.insert(req);
|
||||||
break;
|
break;
|
||||||
case Decision::LockedVersionNotSame:
|
case Decision::LockedVersionNotSame:
|
||||||
qDebug() << reqStr << "already has different version that cannot be changed.";
|
qCDebug(instanceProfileResolveC) << reqStr << "already has different version that cannot be changed.";
|
||||||
succeeded = false;
|
succeeded = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -381,7 +384,7 @@ static bool getTrivialComponentChanges(const ComponentIndex& index, const Requir
|
|||||||
// FIXME: throw all this away and use a graph
|
// FIXME: throw all this away and use a graph
|
||||||
void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
||||||
{
|
{
|
||||||
qDebug() << "Resolving dependencies";
|
qCDebug(instanceProfileResolveC) << "Resolving dependencies";
|
||||||
/*
|
/*
|
||||||
* this is a naive dependency resolving algorithm. all it does is check for following conditions and react in simple ways:
|
* this is a naive dependency resolving algorithm. all it does is check for following conditions and react in simple ways:
|
||||||
* 1. There are conflicting dependencies on the same uid with different exact version numbers
|
* 1. There are conflicting dependencies on the same uid with different exact version numbers
|
||||||
@ -393,8 +396,8 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
*
|
*
|
||||||
* NOTE: this is a placeholder and should eventually be replaced with something 'serious'
|
* NOTE: this is a placeholder and should eventually be replaced with something 'serious'
|
||||||
*/
|
*/
|
||||||
auto& components = d->m_list->d->components;
|
auto& components = d->m_profile->d->components;
|
||||||
auto& componentIndex = d->m_list->d->componentIndex;
|
auto& componentIndex = d->m_profile->d->componentIndex;
|
||||||
|
|
||||||
RequireExSet allRequires;
|
RequireExSet allRequires;
|
||||||
QStringList toRemove;
|
QStringList toRemove;
|
||||||
@ -407,10 +410,10 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
}
|
}
|
||||||
getTrivialRemovals(components, allRequires, toRemove);
|
getTrivialRemovals(components, allRequires, toRemove);
|
||||||
if (!toRemove.isEmpty()) {
|
if (!toRemove.isEmpty()) {
|
||||||
qDebug() << "Removing obsolete components...";
|
qCDebug(instanceProfileResolveC) << "Removing obsolete components...";
|
||||||
for (auto& remove : toRemove) {
|
for (auto& remove : toRemove) {
|
||||||
qDebug() << "Removing" << remove;
|
qCDebug(instanceProfileResolveC) << "Removing" << remove;
|
||||||
d->m_list->remove(remove);
|
d->m_profile->remove(remove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!toRemove.isEmpty());
|
} while (!toRemove.isEmpty());
|
||||||
@ -434,14 +437,14 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
if (toAdd.size()) {
|
if (toAdd.size()) {
|
||||||
// add stuff...
|
// add stuff...
|
||||||
for (auto& add : toAdd) {
|
for (auto& add : toAdd) {
|
||||||
auto component = makeShared<Component>(d->m_list, add.uid);
|
auto component = makeShared<Component>(d->m_profile, add.uid);
|
||||||
if (!add.equalsVersion.isEmpty()) {
|
if (!add.equalsVersion.isEmpty()) {
|
||||||
// exact version
|
// exact version
|
||||||
qDebug() << "Adding" << add.uid << "version" << add.equalsVersion << "at position" << add.indexOfFirstDependee;
|
qCDebug(instanceProfileResolveC) << "Adding" << add.uid << "version" << add.equalsVersion << "at position" << add.indexOfFirstDependee;
|
||||||
component->m_version = add.equalsVersion;
|
component->m_version = add.equalsVersion;
|
||||||
} else {
|
} else {
|
||||||
// version needs to be decided
|
// version needs to be decided
|
||||||
qDebug() << "Adding" << add.uid << "at position" << add.indexOfFirstDependee;
|
qCDebug(instanceProfileResolveC) << "Adding" << add.uid << "at position" << add.indexOfFirstDependee;
|
||||||
// ############################################################################################################
|
// ############################################################################################################
|
||||||
// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded.
|
// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded.
|
||||||
if (!add.suggests.isEmpty()) {
|
if (!add.suggests.isEmpty()) {
|
||||||
@ -464,7 +467,7 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
}
|
}
|
||||||
component->m_dependencyOnly = true;
|
component->m_dependencyOnly = true;
|
||||||
// FIXME: this should not work directly with the component list
|
// FIXME: this should not work directly with the component list
|
||||||
d->m_list->insertComponent(add.indexOfFirstDependee, component);
|
d->m_profile->insertComponent(add.indexOfFirstDependee, component);
|
||||||
componentIndex[add.uid] = component;
|
componentIndex[add.uid] = component;
|
||||||
}
|
}
|
||||||
recursionNeeded = true;
|
recursionNeeded = true;
|
||||||
@ -473,7 +476,7 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
// change a version of something that exists
|
// change a version of something that exists
|
||||||
for (auto& change : toChange) {
|
for (auto& change : toChange) {
|
||||||
// FIXME: this should not work directly with the component list
|
// FIXME: this should not work directly with the component list
|
||||||
qDebug() << "Setting version of " << change.uid << "to" << change.equalsVersion;
|
qCDebug(instanceProfileResolveC) << "Setting version of " << change.uid << "to" << change.equalsVersion;
|
||||||
auto component = componentIndex[change.uid];
|
auto component = componentIndex[change.uid];
|
||||||
component->setVersion(change.equalsVersion);
|
component->setVersion(change.equalsVersion);
|
||||||
}
|
}
|
||||||
@ -490,7 +493,7 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex)
|
void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex)
|
||||||
{
|
{
|
||||||
if (static_cast<size_t>(d->remoteLoadStatusList.size()) < taskIndex) {
|
if (static_cast<size_t>(d->remoteLoadStatusList.size()) < taskIndex) {
|
||||||
qWarning() << "Got task index outside of results" << taskIndex;
|
qCWarning(instanceProfileResolveC) << "Got task index outside of results" << taskIndex;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& taskSlot = d->remoteLoadStatusList[taskIndex];
|
auto& taskSlot = d->remoteLoadStatusList[taskIndex];
|
||||||
@ -498,16 +501,16 @@ void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex)
|
|||||||
disconnect(taskSlot.task.get(), &Task::failed, this, nullptr);
|
disconnect(taskSlot.task.get(), &Task::failed, this, nullptr);
|
||||||
disconnect(taskSlot.task.get(), &Task::aborted, this, nullptr);
|
disconnect(taskSlot.task.get(), &Task::aborted, this, nullptr);
|
||||||
if (taskSlot.finished) {
|
if (taskSlot.finished) {
|
||||||
qWarning() << "Got multiple results from remote load task" << taskIndex;
|
qCWarning(instanceProfileResolveC) << "Got multiple results from remote load task" << taskIndex;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "Remote task" << taskIndex << "succeeded";
|
qCDebug(instanceProfileResolveC) << "Remote task" << taskIndex << "succeeded";
|
||||||
taskSlot.succeeded = false;
|
taskSlot.succeeded = false;
|
||||||
taskSlot.finished = true;
|
taskSlot.finished = true;
|
||||||
d->remoteTasksInProgress--;
|
d->remoteTasksInProgress--;
|
||||||
// update the cached data of the component from the downloaded version file.
|
// update the cached data of the component from the downloaded version file.
|
||||||
if (taskSlot.type == RemoteLoadStatus::Type::Version) {
|
if (taskSlot.type == RemoteLoadStatus::Type::Version) {
|
||||||
auto component = d->m_list->getComponent(taskSlot.PackProfileIndex);
|
auto component = d->m_profile->getComponent(taskSlot.PackProfileIndex);
|
||||||
component->m_loaded = true;
|
component->m_loaded = true;
|
||||||
component->updateCachedData();
|
component->updateCachedData();
|
||||||
}
|
}
|
||||||
@ -517,7 +520,7 @@ void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex)
|
|||||||
void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg)
|
void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg)
|
||||||
{
|
{
|
||||||
if (static_cast<size_t>(d->remoteLoadStatusList.size()) < taskIndex) {
|
if (static_cast<size_t>(d->remoteLoadStatusList.size()) < taskIndex) {
|
||||||
qWarning() << "Got task index outside of results" << taskIndex;
|
qCWarning(instanceProfileResolveC) << "Got task index outside of results" << taskIndex;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& taskSlot = d->remoteLoadStatusList[taskIndex];
|
auto& taskSlot = d->remoteLoadStatusList[taskIndex];
|
||||||
@ -525,10 +528,10 @@ void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg)
|
|||||||
disconnect(taskSlot.task.get(), &Task::failed, this, nullptr);
|
disconnect(taskSlot.task.get(), &Task::failed, this, nullptr);
|
||||||
disconnect(taskSlot.task.get(), &Task::aborted, this, nullptr);
|
disconnect(taskSlot.task.get(), &Task::aborted, this, nullptr);
|
||||||
if (taskSlot.finished) {
|
if (taskSlot.finished) {
|
||||||
qWarning() << "Got multiple results from remote load task" << taskIndex;
|
qCWarning(instanceProfileResolveC) << "Got multiple results from remote load task" << taskIndex;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "Remote task" << taskIndex << "failed: " << msg;
|
qCDebug(instanceProfileResolveC) << "Remote task" << taskIndex << "failed: " << msg;
|
||||||
d->remoteLoadSuccessful = false;
|
d->remoteLoadSuccessful = false;
|
||||||
taskSlot.succeeded = false;
|
taskSlot.succeeded = false;
|
||||||
taskSlot.finished = true;
|
taskSlot.finished = true;
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "net/Mode.h"
|
#include "net/Mode.h"
|
||||||
#include "tasks/Task.h"
|
#include "tasks/Task.h"
|
||||||
|
|
||||||
|
#include "minecraft/ComponentUpdateTask.h"
|
||||||
|
|
||||||
class PackProfile;
|
class PackProfile;
|
||||||
|
|
||||||
struct RemoteLoadStatus {
|
struct RemoteLoadStatus {
|
||||||
@ -18,7 +20,7 @@ struct RemoteLoadStatus {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ComponentUpdateTaskData {
|
struct ComponentUpdateTaskData {
|
||||||
PackProfile* m_list = nullptr;
|
PackProfile* m_profile = nullptr;
|
||||||
QList<RemoteLoadStatus> remoteLoadStatusList;
|
QList<RemoteLoadStatus> remoteLoadStatusList;
|
||||||
bool remoteLoadSuccessful = true;
|
bool remoteLoadSuccessful = true;
|
||||||
size_t remoteTasksInProgress = 0;
|
size_t remoteTasksInProgress = 0;
|
||||||
|
25
launcher/minecraft/Logging.cpp
Normal file
25
launcher/minecraft/Logging.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||||
|
*
|
||||||
|
* 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "minecraft/Logging.h"
|
||||||
|
#include <qloggingcategory.h>
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(instanceProfileC, "launcher.instance.profile")
|
||||||
|
Q_LOGGING_CATEGORY(instanceProfileResolveC, "launcher.instance.profile.resolve")
|
26
launcher/minecraft/Logging.h
Normal file
26
launcher/minecraft/Logging.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||||
|
*
|
||||||
|
* 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(instanceProfileC)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(instanceProfileResolveC)
|
@ -39,7 +39,6 @@
|
|||||||
|
|
||||||
#include <Version.h>
|
#include <Version.h>
|
||||||
#include <qlogging.h>
|
#include <qlogging.h>
|
||||||
#include <qttypetraits.h>
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -66,6 +65,8 @@
|
|||||||
#include "PackProfile_p.h"
|
#include "PackProfile_p.h"
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
|
#include "minecraft/Logging.h"
|
||||||
|
|
||||||
static const QMap<QString, ModPlatform::ModLoaderType> modloaderMapping{ { "net.neoforged", ModPlatform::NeoForge },
|
static const QMap<QString, ModPlatform::ModLoaderType> modloaderMapping{ { "net.neoforged", ModPlatform::NeoForge },
|
||||||
{ "net.minecraftforge", ModPlatform::Forge },
|
{ "net.minecraftforge", ModPlatform::Forge },
|
||||||
{ "net.fabricmc.fabric-loader", ModPlatform::Fabric },
|
{ "net.fabricmc.fabric-loader", ModPlatform::Fabric },
|
||||||
@ -159,16 +160,16 @@ static bool savePackProfile(const QString& filename, const ComponentContainer& c
|
|||||||
obj.insert("components", orderArray);
|
obj.insert("components", orderArray);
|
||||||
QSaveFile outFile(filename);
|
QSaveFile outFile(filename);
|
||||||
if (!outFile.open(QFile::WriteOnly)) {
|
if (!outFile.open(QFile::WriteOnly)) {
|
||||||
qCritical() << "Couldn't open" << outFile.fileName() << "for writing:" << outFile.errorString();
|
qCCritical(instanceProfileC) << "Couldn't open" << outFile.fileName() << "for writing:" << outFile.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
|
auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
|
||||||
if (outFile.write(data) != data.size()) {
|
if (outFile.write(data) != data.size()) {
|
||||||
qCritical() << "Couldn't write all the data into" << outFile.fileName() << "because:" << outFile.errorString();
|
qCCritical(instanceProfileC) << "Couldn't write all the data into" << outFile.fileName() << "because:" << outFile.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!outFile.commit()) {
|
if (!outFile.commit()) {
|
||||||
qCritical() << "Couldn't save" << outFile.fileName() << "because:" << outFile.errorString();
|
qCCritical(instanceProfileC) << "Couldn't save" << outFile.fileName() << "because:" << outFile.errorString();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -181,12 +182,12 @@ static bool loadPackProfile(PackProfile* parent,
|
|||||||
{
|
{
|
||||||
QFile componentsFile(filename);
|
QFile componentsFile(filename);
|
||||||
if (!componentsFile.exists()) {
|
if (!componentsFile.exists()) {
|
||||||
qWarning() << "Components file doesn't exist. This should never happen.";
|
qCWarning(instanceProfileC) << "Components file" << filename << "doesn't exist. This should never happen.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!componentsFile.open(QFile::ReadOnly)) {
|
if (!componentsFile.open(QFile::ReadOnly)) {
|
||||||
qCritical() << "Couldn't open" << componentsFile.fileName() << " for reading:" << componentsFile.errorString();
|
qCCritical(instanceProfileC) << "Couldn't open" << componentsFile.fileName() << " for reading:" << componentsFile.errorString();
|
||||||
qWarning() << "Ignoring overriden order";
|
qCWarning(instanceProfileC) << "Ignoring overridden order";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,8 +195,8 @@ static bool loadPackProfile(PackProfile* parent,
|
|||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error);
|
QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error);
|
||||||
if (error.error != QJsonParseError::NoError) {
|
if (error.error != QJsonParseError::NoError) {
|
||||||
qCritical() << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString();
|
qCCritical(instanceProfileC) << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString();
|
||||||
qWarning() << "Ignoring overriden order";
|
qCWarning(instanceProfileC) << "Ignoring overridden order";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +214,7 @@ static bool loadPackProfile(PackProfile* parent,
|
|||||||
container.append(componentFromJsonV1(parent, componentJsonPattern, comp_obj));
|
container.append(componentFromJsonV1(parent, componentJsonPattern, comp_obj));
|
||||||
}
|
}
|
||||||
} catch ([[maybe_unused]] const JSONValidationError& err) {
|
} catch ([[maybe_unused]] const JSONValidationError& err) {
|
||||||
qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
|
qCCritical(instanceProfileC) << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
|
||||||
container.clear();
|
container.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -246,12 +247,12 @@ void PackProfile::buildingFromScratch()
|
|||||||
void PackProfile::scheduleSave()
|
void PackProfile::scheduleSave()
|
||||||
{
|
{
|
||||||
if (!d->loaded) {
|
if (!d->loaded) {
|
||||||
qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name();
|
qDebug() << d->m_instance->name() << "|" << "Component list should never save if it didn't successfully load";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!d->dirty) {
|
if (!d->dirty) {
|
||||||
d->dirty = true;
|
d->dirty = true;
|
||||||
qDebug() << "Component list save is scheduled for" << d->m_instance->name();
|
qDebug() << d->m_instance->name() << "|" << "Component list save is scheduled";
|
||||||
}
|
}
|
||||||
d->m_saveTimer.start();
|
d->m_saveTimer.start();
|
||||||
}
|
}
|
||||||
@ -278,7 +279,7 @@ QString PackProfile::patchFilePathForUid(const QString& uid) const
|
|||||||
|
|
||||||
void PackProfile::save_internal()
|
void PackProfile::save_internal()
|
||||||
{
|
{
|
||||||
qDebug() << "Component list save performed now for" << d->m_instance->name();
|
qDebug() << d->m_instance->name() << "|" << "Component list save performed now";
|
||||||
auto filename = componentsFilePath();
|
auto filename = componentsFilePath();
|
||||||
savePackProfile(filename, d->components);
|
savePackProfile(filename, d->components);
|
||||||
d->dirty = false;
|
d->dirty = false;
|
||||||
@ -291,7 +292,7 @@ bool PackProfile::load()
|
|||||||
// load the new component list and swap it with the current one...
|
// load the new component list and swap it with the current one...
|
||||||
ComponentContainer newComponents;
|
ComponentContainer newComponents;
|
||||||
if (!loadPackProfile(this, filename, patchesPattern(), newComponents)) {
|
if (!loadPackProfile(this, filename, patchesPattern(), newComponents)) {
|
||||||
qCritical() << "Failed to load the component config for instance" << d->m_instance->name();
|
qCritical() << d->m_instance->name() << "|" << "Failed to load the component config";
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// FIXME: actually use fine-grained updates, not this...
|
// FIXME: actually use fine-grained updates, not this...
|
||||||
@ -304,7 +305,7 @@ bool PackProfile::load()
|
|||||||
d->componentIndex.clear();
|
d->componentIndex.clear();
|
||||||
for (auto component : newComponents) {
|
for (auto component : newComponents) {
|
||||||
if (d->componentIndex.contains(component->m_uid)) {
|
if (d->componentIndex.contains(component->m_uid)) {
|
||||||
qWarning() << "Ignoring duplicate component entry" << component->m_uid;
|
qWarning() << d->m_instance->name() << "|" << "Ignoring duplicate component entry" << component->m_uid;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
connect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
connect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
||||||
@ -352,14 +353,14 @@ void PackProfile::resolve(Net::Mode netmode)
|
|||||||
|
|
||||||
void PackProfile::updateSucceeded()
|
void PackProfile::updateSucceeded()
|
||||||
{
|
{
|
||||||
qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name();
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << "Component list update/resolve task succeeded";
|
||||||
d->m_updateTask.reset();
|
d->m_updateTask.reset();
|
||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackProfile::updateFailed(const QString& error)
|
void PackProfile::updateFailed(const QString& error)
|
||||||
{
|
{
|
||||||
qDebug() << "Component list update/resolve task failed for" << d->m_instance->name() << "Reason:" << error;
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << "Component list update/resolve task failed " << "Reason:" << error;
|
||||||
d->m_updateTask.reset();
|
d->m_updateTask.reset();
|
||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
}
|
}
|
||||||
@ -375,11 +376,11 @@ void PackProfile::insertComponent(size_t index, ComponentPtr component)
|
|||||||
{
|
{
|
||||||
auto id = component->getID();
|
auto id = component->getID();
|
||||||
if (id.isEmpty()) {
|
if (id.isEmpty()) {
|
||||||
qWarning() << "Attempt to add a component with empty ID!";
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|" << "Attempt to add a component with empty ID!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (d->componentIndex.contains(id)) {
|
if (d->componentIndex.contains(id)) {
|
||||||
qWarning() << "Attempt to add a component that is already present!";
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|" << "Attempt to add a component that is already present!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
beginInsertRows(QModelIndex(), static_cast<int>(index), static_cast<int>(index));
|
beginInsertRows(QModelIndex(), static_cast<int>(index), static_cast<int>(index));
|
||||||
@ -394,7 +395,7 @@ void PackProfile::componentDataChanged()
|
|||||||
{
|
{
|
||||||
auto objPtr = qobject_cast<Component*>(sender());
|
auto objPtr = qobject_cast<Component*>(sender());
|
||||||
if (!objPtr) {
|
if (!objPtr) {
|
||||||
qWarning() << "PackProfile got dataChanged signal from a non-Component!";
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|" << "PackProfile got dataChanged signal from a non-Component!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (objPtr->getID() == "net.minecraft") {
|
if (objPtr->getID() == "net.minecraft") {
|
||||||
@ -410,19 +411,20 @@ void PackProfile::componentDataChanged()
|
|||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
qWarning() << "PackProfile got dataChanged signal from a Component which does not belong to it!";
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|"
|
||||||
|
<< "PackProfile got dataChanged signal from a Component which does not belong to it!";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackProfile::remove(const int index)
|
bool PackProfile::remove(const int index)
|
||||||
{
|
{
|
||||||
auto patch = getComponent(index);
|
auto patch = getComponent(index);
|
||||||
if (!patch->isRemovable()) {
|
if (!patch->isRemovable()) {
|
||||||
qWarning() << "Patch" << patch->getID() << "is non-removable";
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|" << "Patch" << patch->getID() << "is non-removable";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!removeComponent_internal(patch)) {
|
if (!removeComponent_internal(patch)) {
|
||||||
qCritical() << "Patch" << patch->getID() << "could not be removed";
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Patch" << patch->getID() << "could not be removed";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,11 +453,11 @@ bool PackProfile::customize(int index)
|
|||||||
{
|
{
|
||||||
auto patch = getComponent(index);
|
auto patch = getComponent(index);
|
||||||
if (!patch->isCustomizable()) {
|
if (!patch->isCustomizable()) {
|
||||||
qDebug() << "Patch" << patch->getID() << "is not customizable";
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << "Patch" << patch->getID() << "is not customizable";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!patch->customize()) {
|
if (!patch->customize()) {
|
||||||
qCritical() << "Patch" << patch->getID() << "could not be customized";
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Patch" << patch->getID() << "could not be customized";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
@ -467,11 +469,11 @@ bool PackProfile::revertToBase(int index)
|
|||||||
{
|
{
|
||||||
auto patch = getComponent(index);
|
auto patch = getComponent(index);
|
||||||
if (!patch->isRevertible()) {
|
if (!patch->isRevertible()) {
|
||||||
qDebug() << "Patch" << patch->getID() << "is not revertible";
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << "Patch" << patch->getID() << "is not revertible";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!patch->revert()) {
|
if (!patch->revert()) {
|
||||||
qCritical() << "Patch" << patch->getID() << "could not be reverted";
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Patch" << patch->getID() << "could not be reverted";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
@ -684,7 +686,8 @@ bool PackProfile::installComponents(QStringList selectedFiles)
|
|||||||
const QString target = FS::PathCombine(patchDir, versionFile->uid + ".json");
|
const QString target = FS::PathCombine(patchDir, versionFile->uid + ".json");
|
||||||
|
|
||||||
if (!QFile::copy(source, target)) {
|
if (!QFile::copy(source, target)) {
|
||||||
qWarning() << "Component" << source << "could not be copied to target" << target;
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|" << "Component" << source << "could not be copied to target"
|
||||||
|
<< target;
|
||||||
result = false;
|
result = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -717,7 +720,8 @@ bool PackProfile::installEmpty(const QString& uid, const QString& name)
|
|||||||
QString patchFileName = FS::PathCombine(patchDir, uid + ".json");
|
QString patchFileName = FS::PathCombine(patchDir, uid + ".json");
|
||||||
QFile file(patchFileName);
|
QFile file(patchFileName);
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
if (!file.open(QFile::WriteOnly)) {
|
||||||
qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString();
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Error opening" << file.fileName()
|
||||||
|
<< "for reading:" << file.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
||||||
@ -737,7 +741,8 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch)
|
|||||||
if (fileName.size()) {
|
if (fileName.size()) {
|
||||||
QFile patchFile(fileName);
|
QFile patchFile(fileName);
|
||||||
if (patchFile.exists() && !patchFile.remove()) {
|
if (patchFile.exists() && !patchFile.remove()) {
|
||||||
qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "File" << fileName
|
||||||
|
<< "could not be removed because:" << patchFile.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -753,7 +758,8 @@ bool PackProfile::removeComponent_internal(ComponentPtr patch)
|
|||||||
if (finfo.exists()) {
|
if (finfo.exists()) {
|
||||||
QFile jarModFile(jar[0]);
|
QFile jarModFile(jar[0]);
|
||||||
if (!jarModFile.remove()) {
|
if (!jarModFile.remove()) {
|
||||||
qCritical() << "File" << jar[0] << "could not be removed because:" << jarModFile.errorString();
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "File" << jar[0]
|
||||||
|
<< "could not be removed because:" << jarModFile.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -810,7 +816,8 @@ bool PackProfile::installJarMods_internal(QStringList filepaths)
|
|||||||
|
|
||||||
QFile file(patchFileName);
|
QFile file(patchFileName);
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
if (!file.open(QFile::WriteOnly)) {
|
||||||
qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString();
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Error opening" << file.fileName()
|
||||||
|
<< "for reading:" << file.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
||||||
@ -864,7 +871,8 @@ bool PackProfile::installCustomJar_internal(QString filepath)
|
|||||||
|
|
||||||
QFile file(patchFileName);
|
QFile file(patchFileName);
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
if (!file.open(QFile::WriteOnly)) {
|
||||||
qCritical() << "Error opening" << file.fileName() << "for reading:" << file.errorString();
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Error opening" << file.fileName()
|
||||||
|
<< "for reading:" << file.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
|
||||||
@ -919,7 +927,8 @@ bool PackProfile::installAgents_internal(QStringList filepaths)
|
|||||||
QFile patchFile(FS::PathCombine(patchDir, targetId + ".json"));
|
QFile patchFile(FS::PathCombine(patchDir, targetId + ".json"));
|
||||||
|
|
||||||
if (!patchFile.open(QFile::WriteOnly)) {
|
if (!patchFile.open(QFile::WriteOnly)) {
|
||||||
qCritical() << "Error opening" << patchFile.fileName() << "for reading:" << patchFile.errorString();
|
qCCritical(instanceProfileC) << d->m_instance->name() << "|" << "Error opening" << patchFile.fileName()
|
||||||
|
<< "for reading:" << patchFile.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,12 +950,13 @@ std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
|
|||||||
try {
|
try {
|
||||||
auto profile = std::make_shared<LaunchProfile>();
|
auto profile = std::make_shared<LaunchProfile>();
|
||||||
for (auto file : d->components) {
|
for (auto file : d->components) {
|
||||||
qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << "Applying" << file->getID()
|
||||||
|
<< (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
|
||||||
file->applyTo(profile.get());
|
file->applyTo(profile.get());
|
||||||
}
|
}
|
||||||
d->m_profile = profile;
|
d->m_profile = profile;
|
||||||
} catch (const Exception& error) {
|
} catch (const Exception& error) {
|
||||||
qWarning() << "Couldn't apply profile patches because: " << error.cause();
|
qCWarning(instanceProfileC) << d->m_instance->name() << "|" << "Couldn't apply profile patches because: " << error.cause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d->m_profile;
|
return d->m_profile;
|
||||||
@ -959,36 +969,58 @@ bool PackProfile::setComponentVersion(const QString& uid, const QString& version
|
|||||||
ComponentPtr component = *iter;
|
ComponentPtr component = *iter;
|
||||||
// set existing
|
// set existing
|
||||||
if (component->revert()) {
|
if (component->revert()) {
|
||||||
component->setVersion(version);
|
|
||||||
component->setImportant(important);
|
|
||||||
// remove linked components to let them re-resolve their versions
|
// remove linked components to let them re-resolve their versions
|
||||||
if (important) {
|
if (important) {
|
||||||
|
component->waitLoadMeta();
|
||||||
auto linked = collectTreeLinked(uid);
|
auto linked = collectTreeLinked(uid);
|
||||||
for (auto comp : linked) {
|
for (auto comp : linked) {
|
||||||
if (comp->isCustom()) {
|
if (comp->isCustom()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (modloaderMapping.contains(comp->getID())) {
|
if (modloaderMapping.contains(comp->getID())) {
|
||||||
qDebug() << comp->getID() << "is a mod loader, setting new recommended version...";
|
qCDebug(instanceProfileC)
|
||||||
|
<< d->m_instance->name() << "|" << comp->getID() << "is a mod loader, updating it to a compatible version";
|
||||||
|
|
||||||
auto versionList = APPLICATION->metadataIndex()->get(comp->getID());
|
auto versionList = APPLICATION->metadataIndex()->get(comp->getID());
|
||||||
|
versionList->waitToLoad();
|
||||||
if (versionList) {
|
if (versionList) {
|
||||||
auto recommended = versionList->getRecommendedForParent(comp->getID(), version);
|
auto recommended = versionList->getRecommendedForParent(uid, version);
|
||||||
if (recommended) {
|
if (recommended) {
|
||||||
qDebug() << "Setting updated loader version: " << comp->getID() << " = " << recommended->version();
|
qCDebug(instanceProfileC)
|
||||||
setComponentVersion(comp->getID(), recommended->version());
|
<< d->m_instance->name() << "|" << "setting updated loader to recommended version: " << comp->getID()
|
||||||
|
<< " = " << recommended->version();
|
||||||
|
comp->setVersion(recommended->version());
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "no recommended version for" << comp->getID();
|
auto latest = versionList->getLatestForParent(uid, version);
|
||||||
|
if (latest) {
|
||||||
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|"
|
||||||
|
<< "setting updated loader to latest compatible version: " << comp->getID()
|
||||||
|
<< " = " << latest->version();
|
||||||
|
comp->setVersion(latest->version());
|
||||||
|
} else {
|
||||||
|
qCDebug(instanceProfileC)
|
||||||
|
<< d->m_instance->name() << "|" << "no compatible version for" << comp->getID() << "removing";
|
||||||
|
remove(comp->getID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "no version list in metadata index for" << comp->getID();
|
qCDebug(instanceProfileC)
|
||||||
|
<< d->m_instance->name() << "|" << "no version list in metadata index for" << comp->getID();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << comp->getID() << ":" << comp->getVersion() << "linked to important component: " << uid
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << comp->getID() << ":" << comp->getVersion()
|
||||||
<< " | Removing so it re-resolves";
|
<< "linked to important component: " << uid << " | Removing so it re-resolves";
|
||||||
remove(comp->getID());
|
remove(comp->getID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// set new version
|
||||||
|
component->setVersion(version);
|
||||||
|
component->setImportant(important);
|
||||||
|
|
||||||
|
if (important) {
|
||||||
|
resolve(Net::Mode::Online);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1006,11 +1038,12 @@ ComponentContainer PackProfile::collectTreeLinked(const QString& uid)
|
|||||||
{
|
{
|
||||||
ComponentContainer linked;
|
ComponentContainer linked;
|
||||||
for (auto comp : d->components) {
|
for (auto comp : d->components) {
|
||||||
qDebug() << "scanning" << comp->getID() << "for tree link";
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << "scanning" << comp->getID() << ":" << comp->getVersion()
|
||||||
|
<< "for tree link";
|
||||||
auto dep = std::find_if(comp->m_cachedRequires.cbegin(), comp->m_cachedRequires.cend(),
|
auto dep = std::find_if(comp->m_cachedRequires.cbegin(), comp->m_cachedRequires.cend(),
|
||||||
[uid](const Meta::Require& req) -> bool { return req.uid == uid; });
|
[uid](const Meta::Require& req) -> bool { return req.uid == uid; });
|
||||||
if (dep != comp->m_cachedRequires.cend()) {
|
if (dep != comp->m_cachedRequires.cend()) {
|
||||||
qDebug() << comp->getID() << "depends on" << uid;
|
qCDebug(instanceProfileResolveC) << comp->getID() << ":" << comp->getVersion() << "depends on" << uid;
|
||||||
linked.append(comp);
|
linked.append(comp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1018,12 +1051,13 @@ ComponentContainer PackProfile::collectTreeLinked(const QString& uid)
|
|||||||
if (iter != d->componentIndex.end()) {
|
if (iter != d->componentIndex.end()) {
|
||||||
ComponentPtr comp = *iter;
|
ComponentPtr comp = *iter;
|
||||||
comp->updateCachedData();
|
comp->updateCachedData();
|
||||||
qDebug() << comp->getID() << "has" << comp->m_cachedRequires.size() << "dependencies";
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << comp->getID() << ":" << comp->getVersion() << "has"
|
||||||
|
<< comp->m_cachedRequires.size() << "dependencies";
|
||||||
for (auto dep : comp->m_cachedRequires) {
|
for (auto dep : comp->m_cachedRequires) {
|
||||||
qDebug() << uid << "depends on" << comp->getID();
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << uid << "depends on" << dep.uid;
|
||||||
auto found = d->componentIndex.find(dep.uid);
|
auto found = d->componentIndex.find(dep.uid);
|
||||||
if (found != d->componentIndex.end()) {
|
if (found != d->componentIndex.end()) {
|
||||||
qDebug() << comp->getID() << "is present";
|
qCDebug(instanceProfileC) << d->m_instance->name() << "|" << (*found)->getID() << "is present";
|
||||||
linked.append(*found);
|
linked.append(*found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace ProviderCapabilities {
|
|||||||
const char* name(ResourceProvider);
|
const char* name(ResourceProvider);
|
||||||
QString readableName(ResourceProvider);
|
QString readableName(ResourceProvider);
|
||||||
QStringList hashType(ResourceProvider);
|
QStringList hashType(ResourceProvider);
|
||||||
}; // namespace ProviderCapabilities
|
} // namespace ProviderCapabilities
|
||||||
|
|
||||||
struct ModpackAuthor {
|
struct ModpackAuthor {
|
||||||
QString name;
|
QString name;
|
||||||
|
Loading…
Reference in New Issue
Block a user