Merge branch 'develop' into refactor-instanceview
This commit is contained in:
@ -10,7 +10,7 @@ typedef std::shared_ptr<Agent> AgentPtr;
|
||||
|
||||
class Agent {
|
||||
public:
|
||||
Agent(LibraryPtr library, QString &argument)
|
||||
Agent(LibraryPtr library, const QString &argument)
|
||||
{
|
||||
m_library = library;
|
||||
m_argument = argument;
|
||||
|
@ -1,8 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (C) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
|
||||
*
|
||||
* 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
|
||||
@ -43,7 +44,6 @@
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include "MMCStrings.h"
|
||||
#include "pathmatcher/RegexpMatcher.h"
|
||||
#include "pathmatcher/MultiMatcher.h"
|
||||
#include "FileSystem.h"
|
||||
@ -439,6 +439,17 @@ QStringList MinecraftInstance::javaArguments()
|
||||
return args;
|
||||
}
|
||||
|
||||
QString MinecraftInstance::getLauncher()
|
||||
{
|
||||
auto profile = m_components->getProfile();
|
||||
|
||||
// use legacy launcher if the traits are set
|
||||
if (profile->getTraits().contains("legacyLaunch") || profile->getTraits().contains("alphaLaunch"))
|
||||
return "legacy";
|
||||
|
||||
return "standard";
|
||||
}
|
||||
|
||||
QMap<QString, QString> MinecraftInstance::getVariables()
|
||||
{
|
||||
QMap<QString, QString> out;
|
||||
@ -630,26 +641,13 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
|
||||
launchScript += "sessionId " + session->session + "\n";
|
||||
}
|
||||
|
||||
// libraries and class path.
|
||||
{
|
||||
QStringList jars, nativeJars;
|
||||
profile->getLibraryFiles(runtimeContext(), jars, nativeJars, getLocalLibraryPath(), binRoot());
|
||||
for(auto file: jars)
|
||||
{
|
||||
launchScript += "cp " + file + "\n";
|
||||
}
|
||||
for(auto file: nativeJars)
|
||||
{
|
||||
launchScript += "ext " + file + "\n";
|
||||
}
|
||||
launchScript += "natives " + getNativePath() + "\n";
|
||||
}
|
||||
|
||||
for (auto trait : profile->getTraits())
|
||||
{
|
||||
launchScript += "traits " + trait + "\n";
|
||||
}
|
||||
launchScript += "launcher onesix\n";
|
||||
|
||||
launchScript += "launcher " + getLauncher() + "\n";
|
||||
|
||||
// qDebug() << "Generated launch script:" << launchScript;
|
||||
return launchScript;
|
||||
}
|
||||
@ -785,6 +783,8 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
||||
out << "Window size: " + QString::number(width) + " x " + QString::number(height);
|
||||
}
|
||||
out << "";
|
||||
out << "Launcher: " + getLauncher();
|
||||
out << "";
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -1096,8 +1096,6 @@ std::shared_ptr<ResourcePackFolderModel> MinecraftInstance::resourcePackList() c
|
||||
if (!m_resource_pack_list)
|
||||
{
|
||||
m_resource_pack_list.reset(new ResourcePackFolderModel(resourcePacksDir()));
|
||||
m_resource_pack_list->enableInteraction(!isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_resource_pack_list.get(), &ResourcePackFolderModel::disableInteraction);
|
||||
}
|
||||
return m_resource_pack_list;
|
||||
}
|
||||
@ -1107,8 +1105,6 @@ std::shared_ptr<TexturePackFolderModel> MinecraftInstance::texturePackList() con
|
||||
if (!m_texture_pack_list)
|
||||
{
|
||||
m_texture_pack_list.reset(new TexturePackFolderModel(texturePacksDir()));
|
||||
m_texture_pack_list->disableInteraction(isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_texture_pack_list.get(), &ModFolderModel::disableInteraction);
|
||||
}
|
||||
return m_texture_pack_list;
|
||||
}
|
||||
@ -1118,8 +1114,6 @@ std::shared_ptr<ShaderPackFolderModel> MinecraftInstance::shaderPackList() const
|
||||
if (!m_shader_pack_list)
|
||||
{
|
||||
m_shader_pack_list.reset(new ShaderPackFolderModel(shaderPacksDir()));
|
||||
m_shader_pack_list->disableInteraction(isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_shader_pack_list.get(), &ModFolderModel::disableInteraction);
|
||||
}
|
||||
return m_shader_pack_list;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
|
||||
*
|
||||
* 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
|
||||
@ -130,6 +131,7 @@ public:
|
||||
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
|
||||
/// get arguments passed to java
|
||||
QStringList javaArguments();
|
||||
QString getLauncher();
|
||||
|
||||
/// get variables for launch command variable substitution/environment
|
||||
QMap<QString, QString> getVariables() override;
|
||||
|
@ -135,7 +135,7 @@ QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo)
|
||||
{
|
||||
out.insert("artifact", downloadInfoToJson(libinfo->artifact));
|
||||
}
|
||||
if(libinfo->classifiers.size())
|
||||
if(!libinfo->classifiers.isEmpty())
|
||||
{
|
||||
QJsonObject classifiersOut;
|
||||
for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++)
|
||||
@ -297,7 +297,7 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
|
||||
{
|
||||
out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
|
||||
}
|
||||
if(in->mojangDownloads.size())
|
||||
if(!in->mojangDownloads.isEmpty())
|
||||
{
|
||||
QJsonObject downloadsOut;
|
||||
for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++)
|
||||
@ -306,6 +306,15 @@ void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObj
|
||||
}
|
||||
out.insert("downloads", downloadsOut);
|
||||
}
|
||||
if(!in->compatibleJavaMajors.isEmpty())
|
||||
{
|
||||
QJsonArray compatibleJavaMajorsOut;
|
||||
for(auto compatibleJavaMajor : in->compatibleJavaMajors)
|
||||
{
|
||||
compatibleJavaMajorsOut.append(compatibleJavaMajor);
|
||||
}
|
||||
out.insert("compatibleJavaMajors", compatibleJavaMajorsOut);
|
||||
}
|
||||
}
|
||||
|
||||
QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch)
|
||||
@ -396,7 +405,7 @@ QJsonObject MojangVersionFormat::libraryToJson(Library *library)
|
||||
iter++;
|
||||
}
|
||||
libRoot.insert("natives", nativeList);
|
||||
if (library->m_extractExcludes.size())
|
||||
if (!library->m_extractExcludes.isEmpty())
|
||||
{
|
||||
QJsonArray excludes;
|
||||
QJsonObject extract;
|
||||
@ -408,7 +417,7 @@ QJsonObject MojangVersionFormat::libraryToJson(Library *library)
|
||||
libRoot.insert("extract", extract);
|
||||
}
|
||||
}
|
||||
if (library->m_rules.size())
|
||||
if (!library->m_rules.isEmpty())
|
||||
{
|
||||
QJsonArray allRules;
|
||||
for (auto &rule : library->m_rules)
|
||||
|
@ -63,13 +63,13 @@ LibraryPtr OneSixVersionFormat::libraryFromJson(ProblemContainer & problems, con
|
||||
QJsonObject OneSixVersionFormat::libraryToJson(Library *library)
|
||||
{
|
||||
QJsonObject libRoot = MojangVersionFormat::libraryToJson(library);
|
||||
if (library->m_absoluteURL.size())
|
||||
if (!library->m_absoluteURL.isEmpty())
|
||||
libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL);
|
||||
if (library->m_hint.size())
|
||||
if (!library->m_hint.isEmpty())
|
||||
libRoot.insert("MMC-hint", library->m_hint);
|
||||
if (library->m_filename.size())
|
||||
if (!library->m_filename.isEmpty())
|
||||
libRoot.insert("MMC-filename", library->m_filename);
|
||||
if (library->m_displayname.size())
|
||||
if (!library->m_displayname.isEmpty())
|
||||
libRoot.insert("MMC-displayname", library->m_displayname);
|
||||
return libRoot;
|
||||
}
|
||||
@ -225,11 +225,10 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc
|
||||
{
|
||||
QJsonObject agentObj = requireObject(agentVal);
|
||||
auto lib = libraryFromJson(*out, agentObj, filename);
|
||||
|
||||
QString arg = "";
|
||||
if (agentObj.contains("argument"))
|
||||
{
|
||||
readString(agentObj, "argument", arg);
|
||||
}
|
||||
readString(agentObj, "argument", arg);
|
||||
|
||||
AgentPtr agent(new Agent(lib, arg));
|
||||
out->agents.append(agent);
|
||||
}
|
||||
@ -332,6 +331,20 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch
|
||||
writeString(root, "appletClass", patch->appletClass);
|
||||
writeStringList(root, "+tweakers", patch->addTweakers);
|
||||
writeStringList(root, "+traits", patch->traits.values());
|
||||
writeStringList(root, "+jvmArgs", patch->addnJvmArguments);
|
||||
if (!patch->agents.isEmpty())
|
||||
{
|
||||
QJsonArray array;
|
||||
for (auto value: patch->agents)
|
||||
{
|
||||
QJsonObject agentOut = OneSixVersionFormat::libraryToJson(value->library().get());
|
||||
if (!value->argument().isEmpty())
|
||||
agentOut.insert("argument", value->argument());
|
||||
|
||||
array.append(agentOut);
|
||||
}
|
||||
root.insert("+agents", array);
|
||||
}
|
||||
if (!patch->libraries.isEmpty())
|
||||
{
|
||||
QJsonArray array;
|
||||
|
@ -1,7 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
|
||||
*
|
||||
* 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
|
||||
@ -47,7 +48,6 @@
|
||||
#include "Exception.h"
|
||||
#include "minecraft/OneSixVersionFormat.h"
|
||||
#include "FileSystem.h"
|
||||
#include "meta/Index.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "Json.h"
|
||||
|
||||
@ -55,7 +55,6 @@
|
||||
#include "PackProfile_p.h"
|
||||
#include "ComponentUpdateTask.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "modplatform/ModAPI.h"
|
||||
|
||||
static const QMap<QString, ModAPI::ModLoaderType> modloaderMapping{
|
||||
@ -613,7 +612,7 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const
|
||||
|
||||
bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index))
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index.parent()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -675,12 +674,12 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
|
||||
|
||||
int PackProfile::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return d->components.size();
|
||||
return parent.isValid() ? 0 : d->components.size();
|
||||
}
|
||||
|
||||
int PackProfile::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return NUM_COLUMNS;
|
||||
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||
}
|
||||
|
||||
void PackProfile::move(const int index, const MoveDirection direction)
|
||||
@ -738,6 +737,11 @@ void PackProfile::installCustomJar(QString selectedFile)
|
||||
installCustomJar_internal(selectedFile);
|
||||
}
|
||||
|
||||
void PackProfile::installAgents(QStringList selectedFiles)
|
||||
{
|
||||
installAgents_internal(selectedFiles);
|
||||
}
|
||||
|
||||
bool PackProfile::installEmpty(const QString& uid, const QString& name)
|
||||
{
|
||||
QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
|
||||
@ -832,18 +836,14 @@ bool PackProfile::installJarMods_internal(QStringList filepaths)
|
||||
for(auto filepath:filepaths)
|
||||
{
|
||||
QFileInfo sourceInfo(filepath);
|
||||
auto uuid = QUuid::createUuid();
|
||||
QString id = uuid.toString().remove('{').remove('}');
|
||||
QString id = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||
QString target_filename = id + ".jar";
|
||||
QString target_id = "org.multimc.jarmod." + id;
|
||||
QString target_id = "custom.jarmod." + id;
|
||||
QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
|
||||
QString finalPath = FS::PathCombine(d->m_instance->jarModsDir(), target_filename);
|
||||
|
||||
QFileInfo targetInfo(finalPath);
|
||||
if(targetInfo.exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT(!targetInfo.exists());
|
||||
|
||||
if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
|
||||
{
|
||||
@ -852,7 +852,7 @@ bool PackProfile::installJarMods_internal(QStringList filepaths)
|
||||
|
||||
auto f = std::make_shared<VersionFile>();
|
||||
auto jarMod = std::make_shared<Library>();
|
||||
jarMod->setRawName(GradleSpecifier("org.multimc.jarmods:" + id + ":1"));
|
||||
jarMod->setRawName(GradleSpecifier("custom.jarmods:" + id + ":1"));
|
||||
jarMod->setFilename(target_filename);
|
||||
jarMod->setDisplayName(sourceInfo.completeBaseName());
|
||||
jarMod->setHint("local");
|
||||
@ -892,7 +892,7 @@ bool PackProfile::installCustomJar_internal(QString filepath)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto specifier = GradleSpecifier("org.multimc:customjar:1");
|
||||
auto specifier = GradleSpecifier("custom:customjar:1");
|
||||
QFileInfo sourceInfo(filepath);
|
||||
QString target_filename = specifier.getFileName();
|
||||
QString target_id = specifier.artifactId();
|
||||
@ -939,6 +939,64 @@ bool PackProfile::installCustomJar_internal(QString filepath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PackProfile::installAgents_internal(QStringList filepaths)
|
||||
{
|
||||
// FIXME code duplication
|
||||
const QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
|
||||
if (!FS::ensureFolderPathExists(patchDir))
|
||||
return false;
|
||||
|
||||
const QString libDir = d->m_instance->getLocalLibraryPath();
|
||||
if (!FS::ensureFolderPathExists(libDir))
|
||||
return false;
|
||||
|
||||
for (const QString& source : filepaths) {
|
||||
const QFileInfo sourceInfo(source);
|
||||
const QString id = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||
const QString targetBaseName = id + ".jar";
|
||||
const QString targetId = "custom.agent." + id;
|
||||
const QString targetName = sourceInfo.completeBaseName() + " (agent)";
|
||||
const QString target = FS::PathCombine(d->m_instance->getLocalLibraryPath(), targetBaseName);
|
||||
|
||||
const QFileInfo targetInfo(target);
|
||||
Q_ASSERT(!targetInfo.exists());
|
||||
|
||||
if (!QFile::copy(source, target))
|
||||
return false;
|
||||
|
||||
auto versionFile = std::make_shared<VersionFile>();
|
||||
|
||||
auto agent = std::make_shared<Library>();
|
||||
|
||||
agent->setRawName("custom.agents:" + id + ":1");
|
||||
agent->setFilename(targetBaseName);
|
||||
agent->setDisplayName(sourceInfo.completeBaseName());
|
||||
agent->setHint("local");
|
||||
|
||||
versionFile->agents.append(std::make_shared<Agent>(agent, QString()));
|
||||
|
||||
versionFile->name = targetName;
|
||||
versionFile->uid = targetId;
|
||||
|
||||
QFile patchFile(FS::PathCombine(patchDir, targetId + ".json"));
|
||||
|
||||
if (!patchFile.open(QFile::WriteOnly)) {
|
||||
qCritical() << "Error opening" << patchFile.fileName() << "for reading:" << patchFile.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
patchFile.write(OneSixVersionFormat::versionFileToJson(versionFile).toJson());
|
||||
patchFile.close();
|
||||
|
||||
appendComponent(new Component(this, versionFile->uid, versionFile));
|
||||
}
|
||||
|
||||
scheduleSave();
|
||||
invalidateLaunchProfile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
|
||||
{
|
||||
if(!d->m_profile)
|
||||
|
@ -1,7 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
|
||||
*
|
||||
* 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
|
||||
@ -85,6 +86,9 @@ public:
|
||||
/// install a jar/zip as a replacement for the main jar
|
||||
void installCustomJar(QString selectedFile);
|
||||
|
||||
/// install Java agent files
|
||||
void installAgents(QStringList selectedFiles);
|
||||
|
||||
enum MoveDirection { MoveUp, MoveDown };
|
||||
/// move component file # up or down the list
|
||||
void move(const int index, const MoveDirection direction);
|
||||
@ -167,6 +171,7 @@ private:
|
||||
bool load();
|
||||
bool installJarMods_internal(QStringList filepaths);
|
||||
bool installCustomJar_internal(QString filepath);
|
||||
bool installAgents_internal(QStringList filepaths);
|
||||
bool removeComponent_internal(ComponentPtr patch);
|
||||
|
||||
private: /* data */
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
class ImplicitRule : public Rule
|
||||
{
|
||||
protected:
|
||||
virtual bool applies(const Library *, const RuntimeContext & runtimeContext)
|
||||
virtual bool applies(const Library *, [[maybe_unused]] const RuntimeContext & runtimeContext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "minecraft/PackProfile.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
|
||||
VanillaCreationTask::VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version)
|
||||
VanillaCreationTask::VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version)
|
||||
: InstanceCreationTask(), m_version(std::move(version)), m_using_loader(true), m_loader(std::move(loader)), m_loader_version(std::move(loader_version))
|
||||
{}
|
||||
|
||||
|
@ -7,16 +7,16 @@
|
||||
class VanillaCreationTask final : public InstanceCreationTask {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VanillaCreationTask(BaseVersionPtr version) : InstanceCreationTask(), m_version(std::move(version)) {}
|
||||
VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version);
|
||||
VanillaCreationTask(BaseVersion::Ptr version) : InstanceCreationTask(), m_version(std::move(version)) {}
|
||||
VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version);
|
||||
|
||||
bool createInstance() override;
|
||||
|
||||
private:
|
||||
// Version to update to / create of the instance.
|
||||
BaseVersionPtr m_version;
|
||||
BaseVersion::Ptr m_version;
|
||||
|
||||
bool m_using_loader = false;
|
||||
QString m_loader;
|
||||
BaseVersionPtr m_loader_version;
|
||||
BaseVersion::Ptr m_loader_version;
|
||||
};
|
||||
|
@ -173,7 +173,7 @@ bool WorldList::resetIcon(int row)
|
||||
|
||||
int WorldList::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 4;
|
||||
return parent.isValid()? 0 : 4;
|
||||
}
|
||||
|
||||
QVariant WorldList::data(const QModelIndex &index, int role) const
|
||||
@ -398,8 +398,8 @@ void WorldList::installWorld(QFileInfo filename)
|
||||
w.install(m_dir.absolutePath());
|
||||
}
|
||||
|
||||
bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
|
||||
const QModelIndex &parent)
|
||||
bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, [[maybe_unused]] int row, [[maybe_unused]] int column,
|
||||
[[maybe_unused]] const QModelIndex &parent)
|
||||
{
|
||||
if (action == Qt::IgnoreAction)
|
||||
return true;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
|
||||
{
|
||||
return size();
|
||||
return parent.isValid() ? 0 : static_cast<int>(size());
|
||||
};
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
|
@ -408,20 +408,20 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
|
||||
}
|
||||
}
|
||||
|
||||
int AccountList::rowCount(const QModelIndex &) const
|
||||
int AccountList::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
// Return count
|
||||
return count();
|
||||
return parent.isValid() ? 0 : count();
|
||||
}
|
||||
|
||||
int AccountList::columnCount(const QModelIndex &) const
|
||||
int AccountList::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return NUM_COLUMNS;
|
||||
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||
}
|
||||
|
||||
Qt::ItemFlags AccountList::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
|
||||
if (index.row() < 0 || index.row() >= rowCount(index.parent()) || !index.isValid())
|
||||
{
|
||||
return Qt::NoItemFlags;
|
||||
}
|
||||
|
@ -71,5 +71,7 @@ void VerifyJavaInstall::executeTask() {
|
||||
{
|
||||
emit logLine(tr("Java version %1").arg(major), MessageLevel::Error);
|
||||
}
|
||||
emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error);
|
||||
|
||||
emitFailed(QString("Incompatible Java major version"));
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in
|
||||
|
||||
int ModFolderModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return NUM_COLUMNS;
|
||||
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||
}
|
||||
|
||||
Task* ModFolderModel::createUpdateTask()
|
||||
|
@ -426,7 +426,7 @@ QVariant ResourceFolderModel::data(const QModelIndex& index, int role) const
|
||||
bool ResourceFolderModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
int row = index.row();
|
||||
if (row < 0 || row >= rowCount(index) || !index.isValid())
|
||||
if (row < 0 || row >= rowCount(index.parent()) || !index.isValid())
|
||||
return false;
|
||||
|
||||
if (role == Qt::CheckStateRole)
|
||||
|
@ -90,8 +90,8 @@ class ResourceFolderModel : public QAbstractListModel {
|
||||
/* Basic columns */
|
||||
enum Columns { ACTIVE_COLUMN = 0, NAME_COLUMN, DATE_COLUMN, NUM_COLUMNS };
|
||||
|
||||
[[nodiscard]] int rowCount(const QModelIndex& = {}) const override { return size(); }
|
||||
[[nodiscard]] int columnCount(const QModelIndex& = {}) const override { return NUM_COLUMNS; };
|
||||
[[nodiscard]] int rowCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : static_cast<int>(size()); }
|
||||
[[nodiscard]] int columnCount(const QModelIndex& parent = {}) const override { return parent.isValid() ? 0 : NUM_COLUMNS; };
|
||||
|
||||
[[nodiscard]] Qt::DropActions supportedDropActions() const override;
|
||||
|
||||
@ -176,7 +176,7 @@ class ResourceFolderModel : public QAbstractListModel {
|
||||
* if the resource is complex and has more stuff to parse.
|
||||
*/
|
||||
virtual void onParseSucceeded(int ticket, QString resource_id);
|
||||
virtual void onParseFailed(int ticket, QString resource_id) {}
|
||||
virtual void onParseFailed(int ticket, QString resource_id) { Q_UNUSED(ticket); Q_UNUSED(resource_id); }
|
||||
|
||||
protected:
|
||||
// Represents the relationship between a column's index (represented by the list index), and it's sorting key.
|
||||
|
@ -15,7 +15,7 @@ static const QMap<int, std::pair<Version, Version>> s_pack_format_versions = {
|
||||
{ 3, { Version("1.11"), Version("1.12.2") } }, { 4, { Version("1.13"), Version("1.14.4") } },
|
||||
{ 5, { Version("1.15"), Version("1.16.1") } }, { 6, { Version("1.16.2"), Version("1.16.5") } },
|
||||
{ 7, { Version("1.17"), Version("1.17.1") } }, { 8, { Version("1.18"), Version("1.18.2") } },
|
||||
{ 9, { Version("1.19"), Version("1.19.2") } },
|
||||
{ 9, { Version("1.19"), Version("1.19.2") } }, { 11, { Version("1.19.3"), Version("1.19.3") } },
|
||||
};
|
||||
|
||||
void ResourcePack::setPackFormat(int new_format_id)
|
||||
@ -114,3 +114,8 @@ bool ResourcePack::applyFilter(QRegularExpression filter) const
|
||||
|
||||
return Resource::applyFilter(filter);
|
||||
}
|
||||
|
||||
bool ResourcePack::valid() const
|
||||
{
|
||||
return m_pack_format != 0;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ class ResourcePack : public Resource {
|
||||
/** Thread-safe. */
|
||||
void setImage(QImage new_image);
|
||||
|
||||
bool valid() const override;
|
||||
|
||||
[[nodiscard]] auto compare(Resource const& other, SortType type) const -> std::pair<int, bool> override;
|
||||
[[nodiscard]] bool applyFilter(QRegularExpression filter) const override;
|
||||
|
||||
|
@ -137,7 +137,7 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient
|
||||
|
||||
int ResourcePackFolderModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return NUM_COLUMNS;
|
||||
return parent.isValid() ? 0 : NUM_COLUMNS;
|
||||
}
|
||||
|
||||
Task* ResourcePackFolderModel::createUpdateTask()
|
||||
|
@ -62,3 +62,8 @@ QPixmap TexturePack::image(QSize size)
|
||||
TexturePackUtils::process(*this);
|
||||
return image(size);
|
||||
}
|
||||
|
||||
bool TexturePack::valid() const
|
||||
{
|
||||
return m_description != nullptr;
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ class TexturePack : public Resource {
|
||||
/** Thread-safe. */
|
||||
void setImage(QImage new_image);
|
||||
|
||||
bool valid() const override;
|
||||
|
||||
protected:
|
||||
mutable QMutex m_data_lock;
|
||||
|
||||
|
@ -121,7 +121,7 @@ ModDetails ReadMCModTOML(QByteArray contents)
|
||||
return {};
|
||||
}
|
||||
auto modsTable = tomlModsTable0->as_table();
|
||||
if (!tomlModsTable0) {
|
||||
if (!modsTable) {
|
||||
qWarning() << "Corrupted mods.toml? [[mods]] was not a table!";
|
||||
return {};
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ LocalModUpdateTask::LocalModUpdateTask(QDir index_dir, ModPlatform::IndexedPack&
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
SetFileAttributesA(index_dir.path().toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
|
||||
SetFileAttributesW(index_dir.path().toStdWString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -28,14 +28,14 @@
|
||||
|
||||
namespace ResourcePackUtils {
|
||||
|
||||
bool process(ResourcePack& pack)
|
||||
bool process(ResourcePack& pack, ProcessingLevel level)
|
||||
{
|
||||
switch (pack.type()) {
|
||||
case ResourceType::FOLDER:
|
||||
ResourcePackUtils::processFolder(pack);
|
||||
ResourcePackUtils::processFolder(pack, level);
|
||||
return true;
|
||||
case ResourceType::ZIPFILE:
|
||||
ResourcePackUtils::processZIP(pack);
|
||||
ResourcePackUtils::processZIP(pack, level);
|
||||
return true;
|
||||
default:
|
||||
qWarning() << "Invalid type for resource pack parse task!";
|
||||
@ -43,7 +43,7 @@ bool process(ResourcePack& pack)
|
||||
}
|
||||
}
|
||||
|
||||
void processFolder(ResourcePack& pack)
|
||||
void processFolder(ResourcePack& pack, ProcessingLevel level)
|
||||
{
|
||||
Q_ASSERT(pack.type() == ResourceType::FOLDER);
|
||||
|
||||
@ -60,6 +60,9 @@ void processFolder(ResourcePack& pack)
|
||||
mcmeta_file.close();
|
||||
}
|
||||
|
||||
if (level == ProcessingLevel::BasicInfoOnly)
|
||||
return;
|
||||
|
||||
QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
|
||||
if (image_file_info.isFile()) {
|
||||
QFile mcmeta_file(image_file_info.filePath());
|
||||
@ -74,7 +77,7 @@ void processFolder(ResourcePack& pack)
|
||||
}
|
||||
}
|
||||
|
||||
void processZIP(ResourcePack& pack)
|
||||
void processZIP(ResourcePack& pack, ProcessingLevel level)
|
||||
{
|
||||
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
|
||||
|
||||
@ -98,6 +101,11 @@ void processZIP(ResourcePack& pack)
|
||||
file.close();
|
||||
}
|
||||
|
||||
if (level == ProcessingLevel::BasicInfoOnly) {
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (zip.setCurrentFile("pack.png")) {
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCritical() << "Failed to open file in zip.";
|
||||
@ -138,6 +146,13 @@ void processPackPNG(ResourcePack& pack, QByteArray&& raw_data)
|
||||
qWarning() << "Failed to parse pack.png.";
|
||||
}
|
||||
}
|
||||
|
||||
bool validate(QFileInfo file)
|
||||
{
|
||||
ResourcePack rp{ file };
|
||||
return ResourcePackUtils::process(rp, ProcessingLevel::BasicInfoOnly) && rp.valid();
|
||||
}
|
||||
|
||||
} // namespace ResourcePackUtils
|
||||
|
||||
LocalResourcePackParseTask::LocalResourcePackParseTask(int token, ResourcePack& rp)
|
||||
@ -152,8 +167,6 @@ bool LocalResourcePackParseTask::abort()
|
||||
|
||||
void LocalResourcePackParseTask::executeTask()
|
||||
{
|
||||
Q_ASSERT(m_resource_pack.valid());
|
||||
|
||||
if (!ResourcePackUtils::process(m_resource_pack))
|
||||
return;
|
||||
|
||||
|
@ -26,13 +26,19 @@
|
||||
#include "tasks/Task.h"
|
||||
|
||||
namespace ResourcePackUtils {
|
||||
bool process(ResourcePack& pack);
|
||||
|
||||
void processZIP(ResourcePack& pack);
|
||||
void processFolder(ResourcePack& pack);
|
||||
enum class ProcessingLevel { Full, BasicInfoOnly };
|
||||
|
||||
bool process(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full);
|
||||
|
||||
void processZIP(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full);
|
||||
void processFolder(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full);
|
||||
|
||||
void processMCMeta(ResourcePack& pack, QByteArray&& raw_data);
|
||||
void processPackPNG(ResourcePack& pack, QByteArray&& raw_data);
|
||||
|
||||
/** Checks whether a file is valid as a resource pack or not. */
|
||||
bool validate(QFileInfo file);
|
||||
} // namespace ResourcePackUtils
|
||||
|
||||
class LocalResourcePackParseTask : public Task {
|
||||
|
@ -28,14 +28,14 @@
|
||||
|
||||
namespace TexturePackUtils {
|
||||
|
||||
bool process(TexturePack& pack)
|
||||
bool process(TexturePack& pack, ProcessingLevel level)
|
||||
{
|
||||
switch (pack.type()) {
|
||||
case ResourceType::FOLDER:
|
||||
TexturePackUtils::processFolder(pack);
|
||||
TexturePackUtils::processFolder(pack, level);
|
||||
return true;
|
||||
case ResourceType::ZIPFILE:
|
||||
TexturePackUtils::processZIP(pack);
|
||||
TexturePackUtils::processZIP(pack, level);
|
||||
return true;
|
||||
default:
|
||||
qWarning() << "Invalid type for resource pack parse task!";
|
||||
@ -43,7 +43,7 @@ bool process(TexturePack& pack)
|
||||
}
|
||||
}
|
||||
|
||||
void processFolder(TexturePack& pack)
|
||||
void processFolder(TexturePack& pack, ProcessingLevel level)
|
||||
{
|
||||
Q_ASSERT(pack.type() == ResourceType::FOLDER);
|
||||
|
||||
@ -60,6 +60,9 @@ void processFolder(TexturePack& pack)
|
||||
mcmeta_file.close();
|
||||
}
|
||||
|
||||
if (level == ProcessingLevel::BasicInfoOnly)
|
||||
return;
|
||||
|
||||
QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
|
||||
if (image_file_info.isFile()) {
|
||||
QFile mcmeta_file(image_file_info.filePath());
|
||||
@ -74,7 +77,7 @@ void processFolder(TexturePack& pack)
|
||||
}
|
||||
}
|
||||
|
||||
void processZIP(TexturePack& pack)
|
||||
void processZIP(TexturePack& pack, ProcessingLevel level)
|
||||
{
|
||||
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
|
||||
|
||||
@ -98,6 +101,11 @@ void processZIP(TexturePack& pack)
|
||||
file.close();
|
||||
}
|
||||
|
||||
if (level == ProcessingLevel::BasicInfoOnly) {
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (zip.setCurrentFile("pack.png")) {
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCritical() << "Failed to open file in zip.";
|
||||
@ -129,6 +137,13 @@ void processPackPNG(TexturePack& pack, QByteArray&& raw_data)
|
||||
qWarning() << "Failed to parse pack.png.";
|
||||
}
|
||||
}
|
||||
|
||||
bool validate(QFileInfo file)
|
||||
{
|
||||
TexturePack rp{ file };
|
||||
return TexturePackUtils::process(rp, ProcessingLevel::BasicInfoOnly) && rp.valid();
|
||||
}
|
||||
|
||||
} // namespace TexturePackUtils
|
||||
|
||||
LocalTexturePackParseTask::LocalTexturePackParseTask(int token, TexturePack& rp)
|
||||
@ -143,8 +158,6 @@ bool LocalTexturePackParseTask::abort()
|
||||
|
||||
void LocalTexturePackParseTask::executeTask()
|
||||
{
|
||||
Q_ASSERT(m_texture_pack.valid());
|
||||
|
||||
if (!TexturePackUtils::process(m_texture_pack))
|
||||
return;
|
||||
|
||||
|
@ -27,13 +27,19 @@
|
||||
#include "tasks/Task.h"
|
||||
|
||||
namespace TexturePackUtils {
|
||||
bool process(TexturePack& pack);
|
||||
|
||||
void processZIP(TexturePack& pack);
|
||||
void processFolder(TexturePack& pack);
|
||||
enum class ProcessingLevel { Full, BasicInfoOnly };
|
||||
|
||||
bool process(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full);
|
||||
|
||||
void processZIP(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full);
|
||||
void processFolder(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full);
|
||||
|
||||
void processPackTXT(TexturePack& pack, QByteArray&& raw_data);
|
||||
void processPackPNG(TexturePack& pack, QByteArray&& raw_data);
|
||||
|
||||
/** Checks whether a file is valid as a texture pack or not. */
|
||||
bool validate(QFileInfo file);
|
||||
} // namespace TexturePackUtils
|
||||
|
||||
class LocalTexturePackParseTask : public Task {
|
||||
|
Reference in New Issue
Block a user