From 64c51a70a3aa110131fb6ad0cabc07ccfdcbb1c0 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 9 Dec 2022 20:26:05 -0700
Subject: feat: add initial support for parseing datapacks
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/CMakeLists.txt | 4 +
launcher/minecraft/mod/DataPack.cpp | 110 ++++++++++++++
launcher/minecraft/mod/DataPack.h | 73 +++++++++
launcher/minecraft/mod/ResourcePack.cpp | 4 +-
.../minecraft/mod/tasks/LocalDataPackParseTask.cpp | 169 +++++++++++++++++++++
.../minecraft/mod/tasks/LocalDataPackParseTask.h | 64 ++++++++
.../mod/tasks/LocalResourcePackParseTask.cpp | 82 +++++++---
.../mod/tasks/LocalResourcePackParseTask.h | 8 +-
.../mod/tasks/LocalTexturePackParseTask.cpp | 59 ++++---
.../mod/tasks/LocalTexturePackParseTask.h | 8 +-
tests/CMakeLists.txt | 3 +
tests/DataPackParse_test.cpp | 76 +++++++++
.../DataPackParse/another_test_folder/pack.mcmeta | 6 +
.../DataPackParse/test_data_pack_boogaloo.zip | Bin 0 -> 898 bytes
.../testdata/DataPackParse/test_folder/pack.mcmeta | 6 +
15 files changed, 622 insertions(+), 50 deletions(-)
create mode 100644 launcher/minecraft/mod/DataPack.cpp
create mode 100644 launcher/minecraft/mod/DataPack.h
create mode 100644 launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp
create mode 100644 launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
create mode 100644 tests/DataPackParse_test.cpp
create mode 100644 tests/testdata/DataPackParse/another_test_folder/pack.mcmeta
create mode 100644 tests/testdata/DataPackParse/test_data_pack_boogaloo.zip
create mode 100644 tests/testdata/DataPackParse/test_folder/pack.mcmeta
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index a0d92b6e..c12e6740 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -331,6 +331,8 @@ set(MINECRAFT_SOURCES
minecraft/mod/Resource.cpp
minecraft/mod/ResourceFolderModel.h
minecraft/mod/ResourceFolderModel.cpp
+ minecraft/mod/DataPack.h
+ minecraft/mod/DataPack.cpp
minecraft/mod/ResourcePack.h
minecraft/mod/ResourcePack.cpp
minecraft/mod/ResourcePackFolderModel.h
@@ -347,6 +349,8 @@ set(MINECRAFT_SOURCES
minecraft/mod/tasks/LocalModParseTask.cpp
minecraft/mod/tasks/LocalModUpdateTask.h
minecraft/mod/tasks/LocalModUpdateTask.cpp
+ minecraft/mod/tasks/LocalDataPackParseTask.h
+ minecraft/mod/tasks/LocalDataPackParseTask.cpp
minecraft/mod/tasks/LocalResourcePackParseTask.h
minecraft/mod/tasks/LocalResourcePackParseTask.cpp
minecraft/mod/tasks/LocalTexturePackParseTask.h
diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp
new file mode 100644
index 00000000..3f275160
--- /dev/null
+++ b/launcher/minecraft/mod/DataPack.cpp
@@ -0,0 +1,110 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "DataPack.h"
+
+#include
+#include
+#include
+
+#include "Version.h"
+
+#include "minecraft/mod/tasks/LocalDataPackParseTask.h"
+
+// Values taken from:
+// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_data_pack#%22pack_format%22
+static const QMap> s_pack_format_versions = {
+ { 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.1") } }, { 9, { Version("1.18.2"), Version("1.18.2") } },
+ { 10, { Version("1.19"), Version("1.19.3") } },
+};
+
+void DataPack::setPackFormat(int new_format_id)
+{
+ QMutexLocker locker(&m_data_lock);
+
+ if (!s_pack_format_versions.contains(new_format_id)) {
+ qWarning() << "Pack format '%1' is not a recognized resource pack id!";
+ }
+
+ m_pack_format = new_format_id;
+}
+
+void DataPack::setDescription(QString new_description)
+{
+ QMutexLocker locker(&m_data_lock);
+
+ m_description = new_description;
+}
+
+std::pair DataPack::compatibleVersions() const
+{
+ if (!s_pack_format_versions.contains(m_pack_format)) {
+ return { {}, {} };
+ }
+
+ return s_pack_format_versions.constFind(m_pack_format).value();
+}
+
+std::pair DataPack::compare(const Resource& other, SortType type) const
+{
+ auto const& cast_other = static_cast(other);
+
+ switch (type) {
+ default: {
+ auto res = Resource::compare(other, type);
+ if (res.first != 0)
+ return res;
+ }
+ case SortType::PACK_FORMAT: {
+ auto this_ver = packFormat();
+ auto other_ver = cast_other.packFormat();
+
+ if (this_ver > other_ver)
+ return { 1, type == SortType::PACK_FORMAT };
+ if (this_ver < other_ver)
+ return { -1, type == SortType::PACK_FORMAT };
+ }
+ }
+ return { 0, false };
+}
+
+bool DataPack::applyFilter(QRegularExpression filter) const
+{
+ if (filter.match(description()).hasMatch())
+ return true;
+
+ if (filter.match(QString::number(packFormat())).hasMatch())
+ return true;
+
+ if (filter.match(compatibleVersions().first.toString()).hasMatch())
+ return true;
+ if (filter.match(compatibleVersions().second.toString()).hasMatch())
+ return true;
+
+ return Resource::applyFilter(filter);
+}
+
+bool DataPack::valid() const
+{
+ return m_pack_format != 0;
+}
diff --git a/launcher/minecraft/mod/DataPack.h b/launcher/minecraft/mod/DataPack.h
new file mode 100644
index 00000000..17d9b65e
--- /dev/null
+++ b/launcher/minecraft/mod/DataPack.h
@@ -0,0 +1,73 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#pragma once
+
+#include "Resource.h"
+
+#include
+
+class Version;
+
+/* TODO:
+ *
+ * Store localized descriptions
+ * */
+
+class DataPack : public Resource {
+ Q_OBJECT
+ public:
+ using Ptr = shared_qobject_ptr;
+
+ DataPack(QObject* parent = nullptr) : Resource(parent) {}
+ DataPack(QFileInfo file_info) : Resource(file_info) {}
+
+ /** Gets the numerical ID of the pack format. */
+ [[nodiscard]] int packFormat() const { return m_pack_format; }
+ /** Gets, respectively, the lower and upper versions supported by the set pack format. */
+ [[nodiscard]] std::pair compatibleVersions() const;
+
+ /** Gets the description of the resource pack. */
+ [[nodiscard]] QString description() const { return m_description; }
+
+ /** Thread-safe. */
+ void setPackFormat(int new_format_id);
+
+ /** Thread-safe. */
+ void setDescription(QString new_description);
+
+ bool valid() const override;
+
+ [[nodiscard]] auto compare(Resource const& other, SortType type) const -> std::pair override;
+ [[nodiscard]] bool applyFilter(QRegularExpression filter) const override;
+
+ protected:
+ mutable QMutex m_data_lock;
+
+ /* The 'version' of a resource pack, as defined in the pack.mcmeta file.
+ * See https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+ */
+ int m_pack_format = 0;
+
+ /** The resource pack's description, as defined in the pack.mcmeta file.
+ */
+ QString m_description;
+};
diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp
index 3a2fd771..47da4fea 100644
--- a/launcher/minecraft/mod/ResourcePack.cpp
+++ b/launcher/minecraft/mod/ResourcePack.cpp
@@ -17,7 +17,9 @@ static const QMap> 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") } }, { 11, { Version("1.19.3"), Version("1.19.3") } },
+ { 9, { Version("1.19"), Version("1.19.2") } },
+ // { 11, { Version("22w42a"), Version("22w44a") } }
+ { 12, { Version("1.19.3"), Version("1.19.3") } },
};
void ResourcePack::setPackFormat(int new_format_id)
diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp
new file mode 100644
index 00000000..8bc8278b
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp
@@ -0,0 +1,169 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "LocalDataPackParseTask.h"
+
+#include "FileSystem.h"
+#include "Json.h"
+
+#include
+#include
+#include
+
+#include
+
+namespace DataPackUtils {
+
+bool process(DataPack& pack, ProcessingLevel level)
+{
+ switch (pack.type()) {
+ case ResourceType::FOLDER:
+ return DataPackUtils::processFolder(pack, level);
+ case ResourceType::ZIPFILE:
+ return DataPackUtils::processZIP(pack, level);
+ default:
+ qWarning() << "Invalid type for resource pack parse task!";
+ return false;
+ }
+}
+
+bool processFolder(DataPack& pack, ProcessingLevel level)
+{
+ Q_ASSERT(pack.type() == ResourceType::FOLDER);
+
+ QFileInfo mcmeta_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.mcmeta"));
+ if (mcmeta_file_info.exists() && mcmeta_file_info.isFile()) {
+ QFile mcmeta_file(mcmeta_file_info.filePath());
+ if (!mcmeta_file.open(QIODevice::ReadOnly))
+ return false; // can't open mcmeta file
+
+ auto data = mcmeta_file.readAll();
+
+ bool mcmeta_result = DataPackUtils::processMCMeta(pack, std::move(data));
+
+ mcmeta_file.close();
+ if (!mcmeta_result) {
+ return false; // mcmeta invalid
+ }
+ } else {
+ return false; // mcmeta file isn't a valid file
+ }
+
+ QFileInfo data_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "data"));
+ if (!data_dir_info.exists() || !data_dir_info.isDir()) {
+ return false; // data dir does not exists or isn't valid
+ }
+
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ return true; // only need basic info already checked
+ }
+
+ return true; // all tests passed
+}
+
+bool processZIP(DataPack& pack, ProcessingLevel level)
+{
+ Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
+
+ QuaZip zip(pack.fileinfo().filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return false; // can't open zip file
+
+ QuaZipFile file(&zip);
+
+ if (zip.setCurrentFile("pack.mcmeta")) {
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCritical() << "Failed to open file in zip.";
+ zip.close();
+ return false;
+ }
+
+ auto data = file.readAll();
+
+ bool mcmeta_result = DataPackUtils::processMCMeta(pack, std::move(data));
+
+ file.close();
+ if (!mcmeta_result) {
+ return false; // mcmeta invalid
+ }
+ } else {
+ return false; // could not set pack.mcmeta as current file.
+ }
+
+ QuaZipDir zipDir(&zip);
+ if (!zipDir.exists("/data")) {
+ return false; // data dir does not exists at zip root
+ }
+
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ zip.close();
+ return true; // only need basic info already checked
+ }
+
+ zip.close();
+
+ return true;
+}
+
+// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+bool processMCMeta(DataPack& pack, QByteArray&& raw_data)
+{
+ try {
+ auto json_doc = QJsonDocument::fromJson(raw_data);
+ auto pack_obj = Json::requireObject(json_doc.object(), "pack", {});
+
+ pack.setPackFormat(Json::ensureInteger(pack_obj, "pack_format", 0));
+ pack.setDescription(Json::ensureString(pack_obj, "description", ""));
+ } catch (Json::JsonException& e) {
+ qWarning() << "JsonException: " << e.what() << e.cause();
+ return false;
+ }
+ return true;
+}
+
+bool validate(QFileInfo file)
+{
+ DataPack dp{ file };
+ return DataPackUtils::process(dp, ProcessingLevel::BasicInfoOnly) && dp.valid();
+}
+
+} // namespace DataPackUtils
+
+LocalDataPackParseTask::LocalDataPackParseTask(int token, DataPack& dp)
+ : Task(nullptr, false), m_token(token), m_resource_pack(dp)
+{}
+
+bool LocalDataPackParseTask::abort()
+{
+ m_aborted = true;
+ return true;
+}
+
+void LocalDataPackParseTask::executeTask()
+{
+ if (!DataPackUtils::process(m_resource_pack))
+ return;
+
+ if (m_aborted)
+ emitAborted();
+ else
+ emitSucceeded();
+}
diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
new file mode 100644
index 00000000..ee64df46
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
@@ -0,0 +1,64 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "minecraft/mod/DataPack.h"
+
+#include "tasks/Task.h"
+
+namespace DataPackUtils {
+
+enum class ProcessingLevel { Full, BasicInfoOnly };
+
+bool process(DataPack& pack, ProcessingLevel level = ProcessingLevel::Full);
+
+bool processZIP(DataPack& pack, ProcessingLevel level = ProcessingLevel::Full);
+bool processFolder(DataPack& pack, ProcessingLevel level = ProcessingLevel::Full);
+
+bool processMCMeta(DataPack& pack, QByteArray&& raw_data);
+
+/** Checks whether a file is valid as a resource pack or not. */
+bool validate(QFileInfo file);
+} // namespace ResourcePackUtils
+
+class LocalDataPackParseTask : public Task {
+ Q_OBJECT
+ public:
+ LocalDataPackParseTask(int token, DataPack& rp);
+
+ [[nodiscard]] bool canAbort() const override { return true; }
+ bool abort() override;
+
+ void executeTask() override;
+
+ [[nodiscard]] int token() const { return m_token; }
+
+ private:
+ int m_token;
+
+ DataPack& m_resource_pack;
+
+ bool m_aborted = false;
+};
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
index 6fd4b024..18d7383d 100644
--- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
@@ -23,6 +23,7 @@
#include
#include
+#include
#include
@@ -32,58 +33,74 @@ bool process(ResourcePack& pack, ProcessingLevel level)
{
switch (pack.type()) {
case ResourceType::FOLDER:
- ResourcePackUtils::processFolder(pack, level);
- return true;
+ return ResourcePackUtils::processFolder(pack, level);
case ResourceType::ZIPFILE:
- ResourcePackUtils::processZIP(pack, level);
- return true;
+ return ResourcePackUtils::processZIP(pack, level);
default:
qWarning() << "Invalid type for resource pack parse task!";
return false;
}
}
-void processFolder(ResourcePack& pack, ProcessingLevel level)
+bool processFolder(ResourcePack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::FOLDER);
QFileInfo mcmeta_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.mcmeta"));
- if (mcmeta_file_info.isFile()) {
+ if (mcmeta_file_info.exists() && mcmeta_file_info.isFile()) {
QFile mcmeta_file(mcmeta_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
- return;
+ return false; // can't open mcmeta file
auto data = mcmeta_file.readAll();
- ResourcePackUtils::processMCMeta(pack, std::move(data));
+ bool mcmeta_result = ResourcePackUtils::processMCMeta(pack, std::move(data));
mcmeta_file.close();
+ if (!mcmeta_result) {
+ return false; // mcmeta invalid
+ }
+ } else {
+ return false; // mcmeta file isn't a valid file
}
- if (level == ProcessingLevel::BasicInfoOnly)
- return;
+ QFileInfo assets_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "assets"));
+ if (!assets_dir_info.exists() || !assets_dir_info.isDir()) {
+ return false; // assets dir does not exists or isn't valid
+ }
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ return true; // only need basic info already checked
+ }
+
QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
- if (image_file_info.isFile()) {
+ if (image_file_info.exists() && image_file_info.isFile()) {
QFile mcmeta_file(image_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
- return;
+ return false; // can't open pack.png file
auto data = mcmeta_file.readAll();
- ResourcePackUtils::processPackPNG(pack, std::move(data));
+ bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));
mcmeta_file.close();
+ if (!pack_png_result) {
+ return false; // pack.png invalid
+ }
+ } else {
+ return false; // pack.png does not exists or is not a valid file.
}
+
+ return true; // all tests passed
}
-void processZIP(ResourcePack& pack, ProcessingLevel level)
+bool processZIP(ResourcePack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return;
+ return false; // can't open zip file
QuaZipFile file(&zip);
@@ -91,40 +108,57 @@ void processZIP(ResourcePack& pack, ProcessingLevel level)
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return;
+ return false;
}
auto data = file.readAll();
- ResourcePackUtils::processMCMeta(pack, std::move(data));
+ bool mcmeta_result = ResourcePackUtils::processMCMeta(pack, std::move(data));
file.close();
+ if (!mcmeta_result) {
+ return false; // mcmeta invalid
+ }
+ } else {
+ return false; // could not set pack.mcmeta as current file.
+ }
+
+ QuaZipDir zipDir(&zip);
+ if (!zipDir.exists("/assets")) {
+ return false; // assets dir does not exists at zip root
}
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return;
+ return true; // only need basic info already checked
}
if (zip.setCurrentFile("pack.png")) {
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return;
+ return false;
}
auto data = file.readAll();
- ResourcePackUtils::processPackPNG(pack, std::move(data));
+ bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));
file.close();
+ if (!pack_png_result) {
+ return false; // pack.png invalid
+ }
+ } else {
+ return false; // could not set pack.mcmeta as current file.
}
zip.close();
+
+ return true;
}
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
-void processMCMeta(ResourcePack& pack, QByteArray&& raw_data)
+bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data)
{
try {
auto json_doc = QJsonDocument::fromJson(raw_data);
@@ -134,17 +168,21 @@ void processMCMeta(ResourcePack& pack, QByteArray&& raw_data)
pack.setDescription(Json::ensureString(pack_obj, "description", ""));
} catch (Json::JsonException& e) {
qWarning() << "JsonException: " << e.what() << e.cause();
+ return false;
}
+ return true;
}
-void processPackPNG(ResourcePack& pack, QByteArray&& raw_data)
+bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data)
{
auto img = QImage::fromData(raw_data);
if (!img.isNull()) {
pack.setImage(img);
} else {
qWarning() << "Failed to parse pack.png.";
+ return false;
}
+ return true;
}
bool validate(QFileInfo file)
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
index 69dbd6ad..d0c24c2b 100644
--- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
@@ -31,11 +31,11 @@ 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);
+bool processZIP(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full);
+bool processFolder(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full);
-void processMCMeta(ResourcePack& pack, QByteArray&& raw_data);
-void processPackPNG(ResourcePack& pack, QByteArray&& raw_data);
+bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data);
+bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data);
/** Checks whether a file is valid as a resource pack or not. */
bool validate(QFileInfo file);
diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp
index adb19aca..e4492f12 100644
--- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp
@@ -32,18 +32,16 @@ bool process(TexturePack& pack, ProcessingLevel level)
{
switch (pack.type()) {
case ResourceType::FOLDER:
- TexturePackUtils::processFolder(pack, level);
- return true;
+ return TexturePackUtils::processFolder(pack, level);
case ResourceType::ZIPFILE:
- TexturePackUtils::processZIP(pack, level);
- return true;
+ return TexturePackUtils::processZIP(pack, level);
default:
qWarning() << "Invalid type for resource pack parse task!";
return false;
}
}
-void processFolder(TexturePack& pack, ProcessingLevel level)
+bool processFolder(TexturePack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::FOLDER);
@@ -51,39 +49,51 @@ void processFolder(TexturePack& pack, ProcessingLevel level)
if (mcmeta_file_info.isFile()) {
QFile mcmeta_file(mcmeta_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
- return;
+ return false;
auto data = mcmeta_file.readAll();
- TexturePackUtils::processPackTXT(pack, std::move(data));
+ bool packTXT_result = TexturePackUtils::processPackTXT(pack, std::move(data));
mcmeta_file.close();
+ if (!packTXT_result) {
+ return false;
+ }
+ } else {
+ return false;
}
if (level == ProcessingLevel::BasicInfoOnly)
- return;
+ return true;
QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
if (image_file_info.isFile()) {
QFile mcmeta_file(image_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
- return;
+ return false;
auto data = mcmeta_file.readAll();
- TexturePackUtils::processPackPNG(pack, std::move(data));
+ bool packPNG_result = TexturePackUtils::processPackPNG(pack, std::move(data));
mcmeta_file.close();
+ if (!packPNG_result) {
+ return false;
+ }
+ } else {
+ return false;
}
+
+ return true;
}
-void processZIP(TexturePack& pack, ProcessingLevel level)
+bool processZIP(TexturePack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return;
+ return false;
QuaZipFile file(&zip);
@@ -91,51 +101,62 @@ void processZIP(TexturePack& pack, ProcessingLevel level)
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return;
+ return false;
}
auto data = file.readAll();
- TexturePackUtils::processPackTXT(pack, std::move(data));
+ bool packTXT_result = TexturePackUtils::processPackTXT(pack, std::move(data));
file.close();
+ if (!packTXT_result) {
+ return false;
+ }
}
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return;
+ return false;
}
if (zip.setCurrentFile("pack.png")) {
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return;
+ return false;
}
auto data = file.readAll();
- TexturePackUtils::processPackPNG(pack, std::move(data));
+ bool packPNG_result = TexturePackUtils::processPackPNG(pack, std::move(data));
file.close();
+ if (!packPNG_result) {
+ return false;
+ }
}
zip.close();
+
+ return true;
}
-void processPackTXT(TexturePack& pack, QByteArray&& raw_data)
+bool processPackTXT(TexturePack& pack, QByteArray&& raw_data)
{
pack.setDescription(QString(raw_data));
+ return true;
}
-void processPackPNG(TexturePack& pack, QByteArray&& raw_data)
+bool processPackPNG(TexturePack& pack, QByteArray&& raw_data)
{
auto img = QImage::fromData(raw_data);
if (!img.isNull()) {
pack.setImage(img);
} else {
qWarning() << "Failed to parse pack.png.";
+ return false;
}
+ return true;
}
bool validate(QFileInfo file)
diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h
index 9f7aab75..1589f8cb 100644
--- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.h
@@ -32,11 +32,11 @@ 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);
+bool processZIP(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full);
+bool processFolder(TexturePack& pack, ProcessingLevel level = ProcessingLevel::Full);
-void processPackTXT(TexturePack& pack, QByteArray&& raw_data);
-void processPackPNG(TexturePack& pack, QByteArray&& raw_data);
+bool processPackTXT(TexturePack& pack, QByteArray&& raw_data);
+bool processPackPNG(TexturePack& pack, QByteArray&& raw_data);
/** Checks whether a file is valid as a texture pack or not. */
bool validate(QFileInfo file);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 630f1200..be33b8db 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -27,6 +27,9 @@ ecm_add_test(ResourcePackParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VER
ecm_add_test(TexturePackParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
TEST_NAME TexturePackParse)
+ecm_add_test(DataPackParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
+ TEST_NAME DataPackParse)
+
ecm_add_test(ParseUtils_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
TEST_NAME ParseUtils)
diff --git a/tests/DataPackParse_test.cpp b/tests/DataPackParse_test.cpp
new file mode 100644
index 00000000..7307035f
--- /dev/null
+++ b/tests/DataPackParse_test.cpp
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * PolyMC - Minecraft Launcher
+ * Copyright (c) 2022 flowln
+ *
+ * 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 .
+ */
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+class DataPackParseTest : public QObject {
+ Q_OBJECT
+
+ private slots:
+ void test_parseZIP()
+ {
+ QString source = QFINDTESTDATA("testdata/DataPackParse");
+
+ QString zip_dp = FS::PathCombine(source, "test_data_pack_boogaloo.zip");
+ DataPack pack { QFileInfo(zip_dp) };
+
+ bool valid = DataPackUtils::processZIP(pack);
+
+ QVERIFY(pack.packFormat() == 4);
+ QVERIFY(pack.description() == "Some data pack 2 boobgaloo");
+ QVERIFY(valid == true);
+ }
+
+ void test_parseFolder()
+ {
+ QString source = QFINDTESTDATA("testdata/DataPackParse");
+
+ QString folder_dp = FS::PathCombine(source, "test_folder");
+ DataPack pack { QFileInfo(folder_dp) };
+
+ bool valid = DataPackUtils::processFolder(pack);
+
+ QVERIFY(pack.packFormat() == 10);
+ QVERIFY(pack.description() == "Some data pack, maybe");
+ QVERIFY(valid == true);
+ }
+
+ void test_parseFolder2()
+ {
+ QString source = QFINDTESTDATA("testdata/DataPackParse");
+
+ QString folder_dp = FS::PathCombine(source, "another_test_folder");
+ DataPack pack { QFileInfo(folder_dp) };
+
+ bool valid = DataPackUtils::process(pack);
+
+ QVERIFY(pack.packFormat() == 6);
+ QVERIFY(pack.description() == "Some data pack three, leaves on the tree");
+ QVERIFY(valid == true);
+ }
+};
+
+QTEST_GUILESS_MAIN(DataPackParseTest)
+
+#include "DataPackParse_test.moc"
diff --git a/tests/testdata/DataPackParse/another_test_folder/pack.mcmeta b/tests/testdata/DataPackParse/another_test_folder/pack.mcmeta
new file mode 100644
index 00000000..5509d007
--- /dev/null
+++ b/tests/testdata/DataPackParse/another_test_folder/pack.mcmeta
@@ -0,0 +1,6 @@
+{
+ "pack": {
+ "pack_format": 6,
+ "description": "Some data pack three, leaves on the tree"
+ }
+}
diff --git a/tests/testdata/DataPackParse/test_data_pack_boogaloo.zip b/tests/testdata/DataPackParse/test_data_pack_boogaloo.zip
new file mode 100644
index 00000000..cb0b9f3c
Binary files /dev/null and b/tests/testdata/DataPackParse/test_data_pack_boogaloo.zip differ
diff --git a/tests/testdata/DataPackParse/test_folder/pack.mcmeta b/tests/testdata/DataPackParse/test_folder/pack.mcmeta
new file mode 100644
index 00000000..dbfc7e9b
--- /dev/null
+++ b/tests/testdata/DataPackParse/test_folder/pack.mcmeta
@@ -0,0 +1,6 @@
+{
+ "pack": {
+ "pack_format": 10,
+ "description": "Some data pack, maybe"
+ }
+}
--
cgit
From 25e23e50cadf8e72105ca70e347d65595d2d3f16 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 9 Dec 2022 21:15:39 -0700
Subject: fix: force add of ignored testdata files
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../another_test_folder/data/dummy/tags/item/foo_proof/bar.json | 1 +
.../DataPackParse/test_folder/data/dummy/tags/item/foo_proof/bar.json | 1 +
2 files changed, 2 insertions(+)
create mode 100644 tests/testdata/DataPackParse/another_test_folder/data/dummy/tags/item/foo_proof/bar.json
create mode 100644 tests/testdata/DataPackParse/test_folder/data/dummy/tags/item/foo_proof/bar.json
diff --git a/tests/testdata/DataPackParse/another_test_folder/data/dummy/tags/item/foo_proof/bar.json b/tests/testdata/DataPackParse/another_test_folder/data/dummy/tags/item/foo_proof/bar.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/tests/testdata/DataPackParse/another_test_folder/data/dummy/tags/item/foo_proof/bar.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/tests/testdata/DataPackParse/test_folder/data/dummy/tags/item/foo_proof/bar.json b/tests/testdata/DataPackParse/test_folder/data/dummy/tags/item/foo_proof/bar.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/tests/testdata/DataPackParse/test_folder/data/dummy/tags/item/foo_proof/bar.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
--
cgit
From 878614ff68163bbc95cbfc35611765f21a83bfed Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 10 Dec 2022 00:52:50 -0700
Subject: feat: add a `ModUtils::validate` moves the reading of mod files into
`ModUtils` namespace
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/minecraft/mod/DataPack.cpp | 2 -
launcher/minecraft/mod/Mod.cpp | 10 ++
launcher/minecraft/mod/Mod.h | 3 +
launcher/minecraft/mod/ModDetails.h | 6 +-
.../minecraft/mod/tasks/LocalDataPackParseTask.h | 5 +-
launcher/minecraft/mod/tasks/LocalModParseTask.cpp | 153 +++++++++++++--------
launcher/minecraft/mod/tasks/LocalModParseTask.h | 19 +++
.../mod/tasks/LocalShaderPackParseTask copy.h | 0
.../minecraft/mod/tasks/LocalShaderPackParseTask.h | 0
9 files changed, 136 insertions(+), 62 deletions(-)
create mode 100644 launcher/minecraft/mod/tasks/LocalShaderPackParseTask copy.h
create mode 100644 launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp
index 3f275160..6c333285 100644
--- a/launcher/minecraft/mod/DataPack.cpp
+++ b/launcher/minecraft/mod/DataPack.cpp
@@ -27,8 +27,6 @@
#include "Version.h"
-#include "minecraft/mod/tasks/LocalDataPackParseTask.h"
-
// Values taken from:
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_data_pack#%22pack_format%22
static const QMap> s_pack_format_versions = {
diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp
index 39023f69..8b00354d 100644
--- a/launcher/minecraft/mod/Mod.cpp
+++ b/launcher/minecraft/mod/Mod.cpp
@@ -43,6 +43,7 @@
#include "MetadataHandler.h"
#include "Version.h"
+#include "minecraft/mod/ModDetails.h"
Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details()
{
@@ -68,6 +69,10 @@ void Mod::setMetadata(std::shared_ptr&& metadata)
m_local_details.metadata = metadata;
}
+void Mod::setDetails(const ModDetails& details) {
+ m_local_details = details;
+}
+
std::pair Mod::compare(const Resource& other, SortType type) const
{
auto cast_other = dynamic_cast(&other);
@@ -190,3 +195,8 @@ void Mod::finishResolvingWithDetails(ModDetails&& details)
if (metadata)
setMetadata(std::move(metadata));
}
+
+bool Mod::valid() const
+{
+ return !m_local_details.mod_id.isEmpty();
+}
\ No newline at end of file
diff --git a/launcher/minecraft/mod/Mod.h b/launcher/minecraft/mod/Mod.h
index f336bec4..b6d264fe 100644
--- a/launcher/minecraft/mod/Mod.h
+++ b/launcher/minecraft/mod/Mod.h
@@ -68,6 +68,9 @@ public:
void setStatus(ModStatus status);
void setMetadata(std::shared_ptr&& metadata);
void setMetadata(const Metadata::ModStruct& metadata) { setMetadata(std::make_shared(metadata)); }
+ void setDetails(const ModDetails& details);
+
+ bool valid() const override;
[[nodiscard]] auto compare(Resource const& other, SortType type) const -> std::pair override;
[[nodiscard]] bool applyFilter(QRegularExpression filter) const override;
diff --git a/launcher/minecraft/mod/ModDetails.h b/launcher/minecraft/mod/ModDetails.h
index dd84b0a3..176e4fc1 100644
--- a/launcher/minecraft/mod/ModDetails.h
+++ b/launcher/minecraft/mod/ModDetails.h
@@ -81,7 +81,7 @@ struct ModDetails
ModDetails() = default;
/** Metadata should be handled manually to properly set the mod status. */
- ModDetails(ModDetails& other)
+ ModDetails(const ModDetails& other)
: mod_id(other.mod_id)
, name(other.name)
, version(other.version)
@@ -92,7 +92,7 @@ struct ModDetails
, status(other.status)
{}
- ModDetails& operator=(ModDetails& other)
+ ModDetails& operator=(const ModDetails& other)
{
this->mod_id = other.mod_id;
this->name = other.name;
@@ -106,7 +106,7 @@ struct ModDetails
return *this;
}
- ModDetails& operator=(ModDetails&& other)
+ ModDetails& operator=(const ModDetails&& other)
{
this->mod_id = other.mod_id;
this->name = other.name;
diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
index ee64df46..9f6ece5c 100644
--- a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
@@ -39,9 +39,10 @@ bool processFolder(DataPack& pack, ProcessingLevel level = ProcessingLevel::Full
bool processMCMeta(DataPack& pack, QByteArray&& raw_data);
-/** Checks whether a file is valid as a resource pack or not. */
+/** Checks whether a file is valid as a data pack or not. */
bool validate(QFileInfo file);
-} // namespace ResourcePackUtils
+
+} // namespace DataPackUtils
class LocalDataPackParseTask : public Task {
Q_OBJECT
diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
index 774f6114..e8fd39b6 100644
--- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
@@ -11,9 +11,10 @@
#include "FileSystem.h"
#include "Json.h"
+#include "minecraft/mod/ModDetails.h"
#include "settings/INIFile.h"
-namespace {
+namespace ModUtils {
// NEW format
// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/6f62b37cea040daf350dc253eae6326dd9c822c3
@@ -283,35 +284,45 @@ ModDetails ReadLiteModInfo(QByteArray contents)
return details;
}
-} // namespace
+bool process(Mod& mod, ProcessingLevel level) {
+ switch (mod.type()) {
+ case ResourceType::FOLDER:
+ return processFolder(mod, level);
+ case ResourceType::ZIPFILE:
+ return processZIP(mod, level);
+ case ResourceType::LITEMOD:
+ return processLitemod(mod);
+ default:
+ qWarning() << "Invalid type for resource pack parse task!";
+ return false;
+ }
+}
-LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile)
- : Task(nullptr, false), m_token(token), m_type(type), m_modFile(modFile), m_result(new Result())
-{}
+bool processZIP(Mod& mod, ProcessingLevel level) {
-void LocalModParseTask::processAsZip()
-{
- QuaZip zip(m_modFile.filePath());
+ ModDetails details;
+
+ QuaZip zip(mod.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return;
+ return false;
QuaZipFile file(&zip);
if (zip.setCurrentFile("META-INF/mods.toml")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
- m_result->details = ReadMCModTOML(file.readAll());
+ details = ReadMCModTOML(file.readAll());
file.close();
-
+
// to replace ${file.jarVersion} with the actual version, as needed
- if (m_result->details.version == "${file.jarVersion}") {
+ if (details.version == "${file.jarVersion}") {
if (zip.setCurrentFile("META-INF/MANIFEST.MF")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
// quick and dirty line-by-line parser
@@ -330,93 +341,134 @@ void LocalModParseTask::processAsZip()
manifestVersion = "NONE";
}
- m_result->details.version = manifestVersion;
+ details.version = manifestVersion;
file.close();
}
}
+
zip.close();
- return;
+ mod.setDetails(details);
+
+ return true;
} else if (zip.setCurrentFile("mcmod.info")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
- m_result->details = ReadMCModInfo(file.readAll());
+ details = ReadMCModInfo(file.readAll());
file.close();
zip.close();
- return;
+
+ mod.setDetails(details);
+ return true;
} else if (zip.setCurrentFile("quilt.mod.json")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
- m_result->details = ReadQuiltModInfo(file.readAll());
+ details = ReadQuiltModInfo(file.readAll());
file.close();
zip.close();
- return;
+
+ mod.setDetails(details);
+ return true;
} else if (zip.setCurrentFile("fabric.mod.json")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
- m_result->details = ReadFabricModInfo(file.readAll());
+ details = ReadFabricModInfo(file.readAll());
file.close();
zip.close();
- return;
+
+ mod.setDetails(details);
+ return true;
} else if (zip.setCurrentFile("forgeversion.properties")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
- m_result->details = ReadForgeInfo(file.readAll());
+ details = ReadForgeInfo(file.readAll());
file.close();
zip.close();
- return;
+
+ mod.setDetails(details);
+ return true;
}
zip.close();
+ return false; // no valid mod found in archive
}
-void LocalModParseTask::processAsFolder()
-{
- QFileInfo mcmod_info(FS::PathCombine(m_modFile.filePath(), "mcmod.info"));
- if (mcmod_info.isFile()) {
+bool processFolder(Mod& mod, ProcessingLevel level) {
+
+ ModDetails details;
+
+ QFileInfo mcmod_info(FS::PathCombine(mod.fileinfo().filePath(), "mcmod.info"));
+ if (mcmod_info.exists() && mcmod_info.isFile()) {
QFile mcmod(mcmod_info.filePath());
if (!mcmod.open(QIODevice::ReadOnly))
- return;
+ return false;
auto data = mcmod.readAll();
if (data.isEmpty() || data.isNull())
- return;
- m_result->details = ReadMCModInfo(data);
+ return false;
+ details = ReadMCModInfo(data);
+
+ mod.setDetails(details);
+ return true;
}
+
+ return false; // no valid mcmod.info file found
}
-void LocalModParseTask::processAsLitemod()
-{
- QuaZip zip(m_modFile.filePath());
+bool processLitemod(Mod& mod, ProcessingLevel level) {
+
+ ModDetails details;
+
+ QuaZip zip(mod.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return;
+ return false;
QuaZipFile file(&zip);
if (zip.setCurrentFile("litemod.json")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
- return;
+ return false;
}
- m_result->details = ReadLiteModInfo(file.readAll());
+ details = ReadLiteModInfo(file.readAll());
file.close();
+
+ mod.setDetails(details);
+ return true;
}
zip.close();
+
+ return false; // no valid litemod.json found in archive
}
+/** Checks whether a file is valid as a mod or not. */
+bool validate(QFileInfo file) {
+
+ Mod mod{ file };
+ return ModUtils::process(mod, ProcessingLevel::BasicInfoOnly) && mod.valid();
+}
+
+} // namespace ModUtils
+
+
+LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile)
+ : Task(nullptr, false), m_token(token), m_type(type), m_modFile(modFile), m_result(new Result())
+{}
+
+
bool LocalModParseTask::abort()
{
m_aborted.store(true);
@@ -424,20 +476,11 @@ bool LocalModParseTask::abort()
}
void LocalModParseTask::executeTask()
-{
- switch (m_type) {
- case ResourceType::ZIPFILE:
- processAsZip();
- break;
- case ResourceType::FOLDER:
- processAsFolder();
- break;
- case ResourceType::LITEMOD:
- processAsLitemod();
- break;
- default:
- break;
- }
+{
+ Mod mod{ m_modFile };
+ ModUtils::process(mod, ModUtils::ProcessingLevel::Full);
+
+ m_result->details = mod.details();
if (m_aborted)
emit finished();
diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.h b/launcher/minecraft/mod/tasks/LocalModParseTask.h
index 413eb2d1..c9512166 100644
--- a/launcher/minecraft/mod/tasks/LocalModParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalModParseTask.h
@@ -8,6 +8,25 @@
#include "tasks/Task.h"
+namespace ModUtils {
+
+ModDetails ReadFabricModInfo(QByteArray contents);
+ModDetails ReadQuiltModInfo(QByteArray contents);
+ModDetails ReadForgeInfo(QByteArray contents);
+ModDetails ReadLiteModInfo(QByteArray contents);
+
+enum class ProcessingLevel { Full, BasicInfoOnly };
+
+bool process(Mod& mod, ProcessingLevel level = ProcessingLevel::Full);
+
+bool processZIP(Mod& mod, ProcessingLevel level = ProcessingLevel::Full);
+bool processFolder(Mod& mod, ProcessingLevel level = ProcessingLevel::Full);
+bool processLitemod(Mod& mod, ProcessingLevel level = ProcessingLevel::Full);
+
+/** Checks whether a file is valid as a mod or not. */
+bool validate(QFileInfo file);
+} // namespace ModUtils
+
class LocalModParseTask : public Task
{
Q_OBJECT
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask copy.h b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask copy.h
new file mode 100644
index 00000000..e69de29b
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
new file mode 100644
index 00000000..e69de29b
--
cgit
From ccfe605920fba14d9e798bb26642d22ee45fe860 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 24 Dec 2022 11:22:06 -0700
Subject: feat: add shaderpack validation
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/minecraft/mod/ShaderPack.cpp | 39 +++++++
launcher/minecraft/mod/ShaderPack.h | 66 ++++++++++++
.../minecraft/mod/tasks/LocalDataPackParseTask.h | 2 +-
.../mod/tasks/LocalResourcePackParseTask.cpp | 8 +-
.../mod/tasks/LocalShaderPackParseTask copy.h | 0
.../mod/tasks/LocalShaderPackParseTask.cpp | 116 +++++++++++++++++++++
.../minecraft/mod/tasks/LocalShaderPackParseTask.h | 63 +++++++++++
7 files changed, 289 insertions(+), 5 deletions(-)
create mode 100644 launcher/minecraft/mod/ShaderPack.cpp
create mode 100644 launcher/minecraft/mod/ShaderPack.h
delete mode 100644 launcher/minecraft/mod/tasks/LocalShaderPackParseTask copy.h
create mode 100644 launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
diff --git a/launcher/minecraft/mod/ShaderPack.cpp b/launcher/minecraft/mod/ShaderPack.cpp
new file mode 100644
index 00000000..b8d427c7
--- /dev/null
+++ b/launcher/minecraft/mod/ShaderPack.cpp
@@ -0,0 +1,39 @@
+
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "ShaderPack.h"
+
+#include "minecraft/mod/tasks/LocalShaderPackParseTask.h"
+
+
+void ShaderPack::setPackFormat(ShaderPackFormat new_format)
+{
+ QMutexLocker locker(&m_data_lock);
+
+
+ m_pack_format = new_format;
+}
+
+bool ShaderPack::valid() const
+{
+ return m_pack_format != ShaderPackFormat::INVALID;
+}
diff --git a/launcher/minecraft/mod/ShaderPack.h b/launcher/minecraft/mod/ShaderPack.h
new file mode 100644
index 00000000..e6ee0757
--- /dev/null
+++ b/launcher/minecraft/mod/ShaderPack.h
@@ -0,0 +1,66 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#pragma once
+
+#include "Resource.h"
+
+/* Info:
+ * Currently For Optifine / Iris shader packs,
+ * could be expanded to support others should they exsist?
+ *
+ * This class and enum are mostly here as placeholders for validating
+ * that a shaderpack exsists and is in the right format,
+ * namely that they contain a folder named 'shaders'.
+ *
+ * In the technical sense it would be possible to parse files like `shaders/shaders.properties`
+ * to get information like the availble profiles but this is not all that usefull without more knoledge of the
+ * shader mod used to be able to change settings
+ *
+ */
+
+#include
+
+enum ShaderPackFormat {
+ VALID,
+ INVALID
+};
+
+class ShaderPack : public Resource {
+ Q_OBJECT
+ public:
+ using Ptr = shared_qobject_ptr;
+
+ [[nodiscard]] ShaderPackFormat packFormat() const { return m_pack_format; }
+
+ ShaderPack(QObject* parent = nullptr) : Resource(parent) {}
+ ShaderPack(QFileInfo file_info) : Resource(file_info) {}
+
+ /** Thread-safe. */
+ void setPackFormat(ShaderPackFormat new_format);
+
+ bool valid() const override;
+
+ protected:
+ mutable QMutex m_data_lock;
+
+ ShaderPackFormat m_pack_format = ShaderPackFormat::INVALID;
+};
diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
index 9f6ece5c..54e3d398 100644
--- a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
@@ -47,7 +47,7 @@ bool validate(QFileInfo file);
class LocalDataPackParseTask : public Task {
Q_OBJECT
public:
- LocalDataPackParseTask(int token, DataPack& rp);
+ LocalDataPackParseTask(int token, DataPack& dp);
[[nodiscard]] bool canAbort() const override { return true; }
bool abort() override;
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
index 18d7383d..2c41c9ae 100644
--- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
@@ -75,15 +75,15 @@ bool processFolder(ResourcePack& pack, ProcessingLevel level)
QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
if (image_file_info.exists() && image_file_info.isFile()) {
- QFile mcmeta_file(image_file_info.filePath());
- if (!mcmeta_file.open(QIODevice::ReadOnly))
+ QFile pack_png_file(image_file_info.filePath());
+ if (!pack_png_file.open(QIODevice::ReadOnly))
return false; // can't open pack.png file
- auto data = mcmeta_file.readAll();
+ auto data = pack_png_file.readAll();
bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));
- mcmeta_file.close();
+ pack_png_file.close();
if (!pack_png_result) {
return false; // pack.png invalid
}
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask copy.h b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask copy.h
deleted file mode 100644
index e69de29b..00000000
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
new file mode 100644
index 00000000..088853b9
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
@@ -0,0 +1,116 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "LocalShaderPackParseTask.h"
+
+#include "FileSystem.h"
+
+#include
+#include
+#include
+
+namespace ShaderPackUtils {
+
+bool process(ShaderPack& pack, ProcessingLevel level)
+{
+ switch (pack.type()) {
+ case ResourceType::FOLDER:
+ return ShaderPackUtils::processFolder(pack, level);
+ case ResourceType::ZIPFILE:
+ return ShaderPackUtils::processZIP(pack, level);
+ default:
+ qWarning() << "Invalid type for shader pack parse task!";
+ return false;
+ }
+}
+
+bool processFolder(ShaderPack& pack, ProcessingLevel level)
+{
+ Q_ASSERT(pack.type() == ResourceType::FOLDER);
+
+ QFileInfo shaders_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "shaders"));
+ if (!shaders_dir_info.exists() || !shaders_dir_info.isDir()) {
+ return false; // assets dir does not exists or isn't valid
+ }
+ pack.setPackFormat(ShaderPackFormat::VALID);
+
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ return true; // only need basic info already checked
+ }
+
+ return true; // all tests passed
+}
+
+bool processZIP(ShaderPack& pack, ProcessingLevel level)
+{
+ Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
+
+ QuaZip zip(pack.fileinfo().filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return false; // can't open zip file
+
+ QuaZipFile file(&zip);
+
+ QuaZipDir zipDir(&zip);
+ if (!zipDir.exists("/shaders")) {
+ return false; // assets dir does not exists at zip root
+ }
+ pack.setPackFormat(ShaderPackFormat::VALID);
+
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ zip.close();
+ return true; // only need basic info already checked
+ }
+
+ zip.close();
+
+ return true;
+}
+
+
+bool validate(QFileInfo file)
+{
+ ShaderPack sp{ file };
+ return ShaderPackUtils::process(sp, ProcessingLevel::BasicInfoOnly) && sp.valid();
+}
+
+} // namespace ShaderPackUtils
+
+LocalShaderPackParseTask::LocalShaderPackParseTask(int token, ShaderPack& sp)
+ : Task(nullptr, false), m_token(token), m_shader_pack(sp)
+{}
+
+bool LocalShaderPackParseTask::abort()
+{
+ m_aborted = true;
+ return true;
+}
+
+void LocalShaderPackParseTask::executeTask()
+{
+ if (!ShaderPackUtils::process(m_shader_pack))
+ return;
+
+ if (m_aborted)
+ emitAborted();
+ else
+ emitSucceeded();
+}
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
index e69de29b..5d113508 100644
--- a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
@@ -0,0 +1,63 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+
+#pragma once
+
+#include
+#include
+
+#include "minecraft/mod/ShaderPack.h"
+
+#include "tasks/Task.h"
+
+namespace ShaderPackUtils {
+
+enum class ProcessingLevel { Full, BasicInfoOnly };
+
+bool process(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
+
+bool processZIP(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
+bool processFolder(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
+
+/** Checks whether a file is valid as a resource pack or not. */
+bool validate(QFileInfo file);
+} // namespace ShaderPackUtils
+
+class LocalShaderPackParseTask : public Task {
+ Q_OBJECT
+ public:
+ LocalShaderPackParseTask(int token, ShaderPack& sp);
+
+ [[nodiscard]] bool canAbort() const override { return true; }
+ bool abort() override;
+
+ void executeTask() override;
+
+ [[nodiscard]] int token() const { return m_token; }
+
+ private:
+ int m_token;
+
+ ShaderPack& m_shader_pack;
+
+ bool m_aborted = false;
+};
--
cgit
From eb31a951a18287f943a1e3d021629dde8b73fd15 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 24 Dec 2022 15:58:24 -0700
Subject: feat: worldSave parsing and validation
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/minecraft/mod/WorldSave.cpp | 45 ++++++
launcher/minecraft/mod/WorldSave.h | 67 ++++++++
.../mod/tasks/LocalWorldSaveParseTask.cpp | 177 +++++++++++++++++++++
.../minecraft/mod/tasks/LocalWorldSaveParseTask.h | 62 ++++++++
4 files changed, 351 insertions(+)
create mode 100644 launcher/minecraft/mod/WorldSave.cpp
create mode 100644 launcher/minecraft/mod/WorldSave.h
create mode 100644 launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
create mode 100644 launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
diff --git a/launcher/minecraft/mod/WorldSave.cpp b/launcher/minecraft/mod/WorldSave.cpp
new file mode 100644
index 00000000..9a626fc1
--- /dev/null
+++ b/launcher/minecraft/mod/WorldSave.cpp
@@ -0,0 +1,45 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "WorldSave.h"
+
+#include "minecraft/mod/tasks/LocalWorldSaveParseTask.h"
+
+void WorldSave::setSaveFormat(WorldSaveFormat new_save_format)
+{
+ QMutexLocker locker(&m_data_lock);
+
+
+ m_save_format = new_save_format;
+}
+
+void WorldSave::setSaveDirName(QString dir_name)
+{
+ QMutexLocker locker(&m_data_lock);
+
+
+ m_save_dir_name = dir_name;
+}
+
+bool WorldSave::valid() const
+{
+ return m_save_format != WorldSaveFormat::INVALID;
+}
\ No newline at end of file
diff --git a/launcher/minecraft/mod/WorldSave.h b/launcher/minecraft/mod/WorldSave.h
new file mode 100644
index 00000000..f48f42b9
--- /dev/null
+++ b/launcher/minecraft/mod/WorldSave.h
@@ -0,0 +1,67 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#pragma once
+
+#include "Resource.h"
+
+#include
+
+class Version;
+
+enum WorldSaveFormat {
+ SINGLE,
+ MULTI,
+ INVALID
+};
+
+class WorldSave : public Resource {
+ Q_OBJECT
+ public:
+ using Ptr = shared_qobject_ptr;
+
+ WorldSave(QObject* parent = nullptr) : Resource(parent) {}
+ WorldSave(QFileInfo file_info) : Resource(file_info) {}
+
+ /** Gets the format of the save. */
+ [[nodiscard]] WorldSaveFormat saveFormat() const { return m_save_format; }
+ /** Gets the name of the save dir (first found in multi mode). */
+ [[nodiscard]] QString saveDirName() const { return m_save_dir_name; }
+
+ /** Thread-safe. */
+ void setSaveFormat(WorldSaveFormat new_save_format);
+ /** Thread-safe. */
+ void setSaveDirName(QString dir_name);
+
+ bool valid() const override;
+
+
+ protected:
+ mutable QMutex m_data_lock;
+
+ /* The 'version' of a resource pack, as defined in the pack.mcmeta file.
+ * See https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+ */
+ WorldSaveFormat m_save_format = WorldSaveFormat::INVALID;
+
+ QString m_save_dir_name;
+
+};
diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
new file mode 100644
index 00000000..5405d308
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
@@ -0,0 +1,177 @@
+
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "LocalWorldSaveParseTask.h"
+
+#include "FileSystem.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace WorldSaveUtils {
+
+bool process(WorldSave& pack, ProcessingLevel level)
+{
+ switch (pack.type()) {
+ case ResourceType::FOLDER:
+ return WorldSaveUtils::processFolder(pack, level);
+ case ResourceType::ZIPFILE:
+ return WorldSaveUtils::processZIP(pack, level);
+ default:
+ qWarning() << "Invalid type for shader pack parse task!";
+ return false;
+ }
+}
+
+
+static std::tuple contains_level_dat(QDir dir, bool saves = false)
+{
+ for(auto const& entry : dir.entryInfoList()) {
+ if (!entry.isDir()) {
+ continue;
+ }
+ if (!saves && entry.fileName() == "saves") {
+ return contains_level_dat(QDir(entry.filePath()), true);
+ }
+ QFileInfo level_dat(FS::PathCombine(entry.filePath(), "level.dat"));
+ if (level_dat.exists() && level_dat.isFile()) {
+ return std::make_tuple(true, entry.fileName(), saves);
+ }
+ }
+ return std::make_tuple(false, "", saves);
+}
+
+
+bool processFolder(WorldSave& save, ProcessingLevel level)
+{
+ Q_ASSERT(save.type() == ResourceType::FOLDER);
+
+ auto [ found, save_dir_name, found_saves_dir ] = contains_level_dat(QDir(save.fileinfo().filePath()));
+
+ if (!found) {
+ return false;
+ }
+
+ save.setSaveDirName(save_dir_name);
+
+ if (found_saves_dir) {
+ save.setSaveFormat(WorldSaveFormat::MULTI);
+ } else {
+ save.setSaveFormat(WorldSaveFormat::SINGLE);
+ }
+
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ return true; // only need basic info already checked
+ }
+
+ // resurved for more intensive processing
+
+ return true; // all tests passed
+}
+
+static std::tuple contains_level_dat(QuaZip& zip)
+{
+ bool saves = false;
+ QuaZipDir zipDir(&zip);
+ if (zipDir.exists("/saves")) {
+ saves = true;
+ zipDir.cd("/saves");
+ }
+
+ for (auto const& entry : zipDir.entryList()) {
+ zipDir.cd(entry);
+ if (zipDir.exists("level.dat")) {
+ return std::make_tuple(true, entry, saves);
+ }
+ zipDir.cd("..");
+ }
+ return std::make_tuple(false, "", saves);
+}
+
+bool processZIP(WorldSave& save, ProcessingLevel level)
+{
+ Q_ASSERT(save.type() == ResourceType::ZIPFILE);
+
+ QuaZip zip(save.fileinfo().filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return false; // can't open zip file
+
+ auto [ found, save_dir_name, found_saves_dir ] = contains_level_dat(zip);
+
+
+ if (!found) {
+ return false;
+ }
+
+ save.setSaveDirName(save_dir_name);
+
+ if (found_saves_dir) {
+ save.setSaveFormat(WorldSaveFormat::MULTI);
+ } else {
+ save.setSaveFormat(WorldSaveFormat::SINGLE);
+ }
+
+ if (level == ProcessingLevel::BasicInfoOnly) {
+ zip.close();
+ return true; // only need basic info already checked
+ }
+
+ // resurved for more intensive processing
+
+ zip.close();
+
+ return true;
+}
+
+
+bool validate(QFileInfo file)
+{
+ WorldSave sp{ file };
+ return WorldSaveUtils::process(sp, ProcessingLevel::BasicInfoOnly) && sp.valid();
+}
+
+} // namespace WorldSaveUtils
+
+LocalWorldSaveParseTask::LocalWorldSaveParseTask(int token, WorldSave& save)
+ : Task(nullptr, false), m_token(token), m_save(save)
+{}
+
+bool LocalWorldSaveParseTask::abort()
+{
+ m_aborted = true;
+ return true;
+}
+
+void LocalWorldSaveParseTask::executeTask()
+{
+ if (!WorldSaveUtils::process(m_save))
+ return;
+
+ if (m_aborted)
+ emitAborted();
+ else
+ emitSucceeded();
+}
diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
new file mode 100644
index 00000000..44153735
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
@@ -0,0 +1,62 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#pragma once
+
+#include
+#include
+
+#include "minecraft/mod/WorldSave.h"
+
+#include "tasks/Task.h"
+
+namespace WorldSaveUtils {
+
+enum class ProcessingLevel { Full, BasicInfoOnly };
+
+bool process(WorldSave& save, ProcessingLevel level = ProcessingLevel::Full);
+
+bool processZIP(WorldSave& pack, ProcessingLevel level = ProcessingLevel::Full);
+bool processFolder(WorldSave& pack, ProcessingLevel level = ProcessingLevel::Full);
+
+bool validate(QFileInfo file);
+
+} // namespace WorldSaveUtils
+
+class LocalWorldSaveParseTask : public Task {
+ Q_OBJECT
+ public:
+ LocalWorldSaveParseTask(int token, WorldSave& save);
+
+ [[nodiscard]] bool canAbort() const override { return true; }
+ bool abort() override;
+
+ void executeTask() override;
+
+ [[nodiscard]] int token() const { return m_token; }
+
+ private:
+ int m_token;
+
+ WorldSave& m_save;
+
+ bool m_aborted = false;
+};
\ No newline at end of file
--
cgit
From a7c9b2f172754aa476a23deabe074a649cefdd11 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 24 Dec 2022 17:43:43 -0700
Subject: feat: validate world saves
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/CMakeLists.txt | 8 ++
launcher/minecraft/mod/ShaderPack.h | 2 +-
launcher/minecraft/mod/WorldSave.h | 2 +-
.../mod/tasks/LocalWorldSaveParseTask.cpp | 3 +
tests/CMakeLists.txt | 6 ++
tests/DataPackParse_test.cpp | 7 +-
tests/ShaderPackParse_test.cpp | 77 +++++++++++++++++
tests/WorldSaveParse_test.cpp | 94 +++++++++++++++++++++
tests/testdata/ShaderPackParse/shaderpack1.zip | Bin 0 -> 242 bytes
.../shaderpack2/shaders/shaders.properties | 0
tests/testdata/ShaderPackParse/shaderpack3.zip | Bin 0 -> 128 bytes
tests/testdata/WorldSaveParse/minecraft_save_1.zip | Bin 0 -> 184 bytes
tests/testdata/WorldSaveParse/minecraft_save_2.zip | Bin 0 -> 352 bytes
.../minecraft_save_3/world_3/level.dat | 0
.../minecraft_save_4/saves/world_4/level.dat | 0
15 files changed, 195 insertions(+), 4 deletions(-)
create mode 100644 tests/ShaderPackParse_test.cpp
create mode 100644 tests/WorldSaveParse_test.cpp
create mode 100644 tests/testdata/ShaderPackParse/shaderpack1.zip
create mode 100644 tests/testdata/ShaderPackParse/shaderpack2/shaders/shaders.properties
create mode 100644 tests/testdata/ShaderPackParse/shaderpack3.zip
create mode 100644 tests/testdata/WorldSaveParse/minecraft_save_1.zip
create mode 100644 tests/testdata/WorldSaveParse/minecraft_save_2.zip
create mode 100644 tests/testdata/WorldSaveParse/minecraft_save_3/world_3/level.dat
create mode 100644 tests/testdata/WorldSaveParse/minecraft_save_4/saves/world_4/level.dat
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index c12e6740..853e1c03 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -339,6 +339,10 @@ set(MINECRAFT_SOURCES
minecraft/mod/ResourcePackFolderModel.cpp
minecraft/mod/TexturePack.h
minecraft/mod/TexturePack.cpp
+ minecraft/mod/ShaderPack.h
+ minecraft/mod/ShaderPack.cpp
+ minecraft/mod/WorldSave.h
+ minecraft/mod/WorldSave.cpp
minecraft/mod/TexturePackFolderModel.h
minecraft/mod/TexturePackFolderModel.cpp
minecraft/mod/ShaderPackFolderModel.h
@@ -355,6 +359,10 @@ set(MINECRAFT_SOURCES
minecraft/mod/tasks/LocalResourcePackParseTask.cpp
minecraft/mod/tasks/LocalTexturePackParseTask.h
minecraft/mod/tasks/LocalTexturePackParseTask.cpp
+ minecraft/mod/tasks/LocalShaderPackParseTask.h
+ minecraft/mod/tasks/LocalShaderPackParseTask.cpp
+ minecraft/mod/tasks/LocalWorldSaveParseTask.h
+ minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
# Assets
minecraft/AssetsUtils.h
diff --git a/launcher/minecraft/mod/ShaderPack.h b/launcher/minecraft/mod/ShaderPack.h
index e6ee0757..a0dad7a1 100644
--- a/launcher/minecraft/mod/ShaderPack.h
+++ b/launcher/minecraft/mod/ShaderPack.h
@@ -39,7 +39,7 @@
#include
-enum ShaderPackFormat {
+enum class ShaderPackFormat {
VALID,
INVALID
};
diff --git a/launcher/minecraft/mod/WorldSave.h b/launcher/minecraft/mod/WorldSave.h
index f48f42b9..f703f34c 100644
--- a/launcher/minecraft/mod/WorldSave.h
+++ b/launcher/minecraft/mod/WorldSave.h
@@ -27,7 +27,7 @@
class Version;
-enum WorldSaveFormat {
+enum class WorldSaveFormat {
SINGLE,
MULTI,
INVALID
diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
index 5405d308..b7f2420a 100644
--- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
@@ -121,6 +121,9 @@ bool processZIP(WorldSave& save, ProcessingLevel level)
auto [ found, save_dir_name, found_saves_dir ] = contains_level_dat(zip);
+ if (save_dir_name.endsWith("/")) {
+ save_dir_name.chop(1);
+ }
if (!found) {
return false;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index be33b8db..9f84a9a7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -30,6 +30,12 @@ ecm_add_test(TexturePackParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERS
ecm_add_test(DataPackParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
TEST_NAME DataPackParse)
+ecm_add_test(ShaderPackParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
+ TEST_NAME ShaderPackParse)
+
+ecm_add_test(WorldSaveParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
+ TEST_NAME WorldSaveParse)
+
ecm_add_test(ParseUtils_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
TEST_NAME ParseUtils)
diff --git a/tests/DataPackParse_test.cpp b/tests/DataPackParse_test.cpp
index 7307035f..61ce1e2b 100644
--- a/tests/DataPackParse_test.cpp
+++ b/tests/DataPackParse_test.cpp
@@ -1,7 +1,10 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
// SPDX-License-Identifier: GPL-3.0-only
+
/*
- * PolyMC - Minecraft Launcher
- * Copyright (c) 2022 flowln
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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
diff --git a/tests/ShaderPackParse_test.cpp b/tests/ShaderPackParse_test.cpp
new file mode 100644
index 00000000..7df105c6
--- /dev/null
+++ b/tests/ShaderPackParse_test.cpp
@@ -0,0 +1,77 @@
+
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+class ShaderPackParseTest : public QObject {
+ Q_OBJECT
+
+ private slots:
+ void test_parseZIP()
+ {
+ QString source = QFINDTESTDATA("testdata/ShaderPackParse");
+
+ QString zip_sp = FS::PathCombine(source, "shaderpack1.zip");
+ ShaderPack pack { QFileInfo(zip_sp) };
+
+ bool valid = ShaderPackUtils::processZIP(pack);
+
+ QVERIFY(pack.packFormat() == ShaderPackFormat::VALID);
+ QVERIFY(valid == true);
+ }
+
+ void test_parseFolder()
+ {
+ QString source = QFINDTESTDATA("testdata/ShaderPackParse");
+
+ QString folder_sp = FS::PathCombine(source, "shaderpack2");
+ ShaderPack pack { QFileInfo(folder_sp) };
+
+ bool valid = ShaderPackUtils::processFolder(pack);
+
+ QVERIFY(pack.packFormat() == ShaderPackFormat::VALID);
+ QVERIFY(valid == true);
+ }
+
+ void test_parseZIP2()
+ {
+ QString source = QFINDTESTDATA("testdata/ShaderPackParse");
+
+ QString folder_sp = FS::PathCombine(source, "shaderpack3.zip");
+ ShaderPack pack { QFileInfo(folder_sp) };
+
+ bool valid = ShaderPackUtils::process(pack);
+
+ QVERIFY(pack.packFormat() == ShaderPackFormat::INVALID);
+ QVERIFY(valid == false);
+ }
+};
+
+QTEST_GUILESS_MAIN(ShaderPackParseTest)
+
+#include "ShaderPackParse_test.moc"
diff --git a/tests/WorldSaveParse_test.cpp b/tests/WorldSaveParse_test.cpp
new file mode 100644
index 00000000..4a8c3d29
--- /dev/null
+++ b/tests/WorldSaveParse_test.cpp
@@ -0,0 +1,94 @@
+
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+class WorldSaveParseTest : public QObject {
+ Q_OBJECT
+
+ private slots:
+ void test_parseZIP()
+ {
+ QString source = QFINDTESTDATA("testdata/WorldSaveParse");
+
+ QString zip_ws = FS::PathCombine(source, "minecraft_save_1.zip") ;
+ WorldSave save { QFileInfo(zip_ws) };
+
+ bool valid = WorldSaveUtils::processZIP(save);
+
+ QVERIFY(save.saveFormat() == WorldSaveFormat::SINGLE);
+ QVERIFY(save.saveDirName() == "world_1");
+ QVERIFY(valid == true);
+ }
+
+ void test_parse_ZIP2()
+ {
+ QString source = QFINDTESTDATA("testdata/WorldSaveParse");
+
+ QString zip_ws = FS::PathCombine(source, "minecraft_save_2.zip") ;
+ WorldSave save { QFileInfo(zip_ws) };
+
+ bool valid = WorldSaveUtils::processZIP(save);
+
+ QVERIFY(save.saveFormat() == WorldSaveFormat::MULTI);
+ QVERIFY(save.saveDirName() == "world_2");
+ QVERIFY(valid == true);
+ }
+
+ void test_parseFolder()
+ {
+ QString source = QFINDTESTDATA("testdata/WorldSaveParse");
+
+ QString folder_ws = FS::PathCombine(source, "minecraft_save_3");
+ WorldSave save { QFileInfo(folder_ws) };
+
+ bool valid = WorldSaveUtils::processFolder(save);
+
+ QVERIFY(save.saveFormat() == WorldSaveFormat::SINGLE);
+ QVERIFY(save.saveDirName() == "world_3");
+ QVERIFY(valid == true);
+ }
+
+ void test_parseFolder2()
+ {
+ QString source = QFINDTESTDATA("testdata/WorldSaveParse");
+
+ QString folder_ws = FS::PathCombine(source, "minecraft_save_4");
+ WorldSave save { QFileInfo(folder_ws) };
+
+ bool valid = WorldSaveUtils::process(save);
+
+ QVERIFY(save.saveFormat() == WorldSaveFormat::MULTI);
+ QVERIFY(save.saveDirName() == "world_4");
+ QVERIFY(valid == true);
+ }
+};
+
+QTEST_GUILESS_MAIN(WorldSaveParseTest)
+
+#include "WorldSaveParse_test.moc"
diff --git a/tests/testdata/ShaderPackParse/shaderpack1.zip b/tests/testdata/ShaderPackParse/shaderpack1.zip
new file mode 100644
index 00000000..9a8fb186
Binary files /dev/null and b/tests/testdata/ShaderPackParse/shaderpack1.zip differ
diff --git a/tests/testdata/ShaderPackParse/shaderpack2/shaders/shaders.properties b/tests/testdata/ShaderPackParse/shaderpack2/shaders/shaders.properties
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/testdata/ShaderPackParse/shaderpack3.zip b/tests/testdata/ShaderPackParse/shaderpack3.zip
new file mode 100644
index 00000000..dbec042d
Binary files /dev/null and b/tests/testdata/ShaderPackParse/shaderpack3.zip differ
diff --git a/tests/testdata/WorldSaveParse/minecraft_save_1.zip b/tests/testdata/WorldSaveParse/minecraft_save_1.zip
new file mode 100644
index 00000000..832a243d
Binary files /dev/null and b/tests/testdata/WorldSaveParse/minecraft_save_1.zip differ
diff --git a/tests/testdata/WorldSaveParse/minecraft_save_2.zip b/tests/testdata/WorldSaveParse/minecraft_save_2.zip
new file mode 100644
index 00000000..6c895176
Binary files /dev/null and b/tests/testdata/WorldSaveParse/minecraft_save_2.zip differ
diff --git a/tests/testdata/WorldSaveParse/minecraft_save_3/world_3/level.dat b/tests/testdata/WorldSaveParse/minecraft_save_3/world_3/level.dat
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/testdata/WorldSaveParse/minecraft_save_4/saves/world_4/level.dat b/tests/testdata/WorldSaveParse/minecraft_save_4/saves/world_4/level.dat
new file mode 100644
index 00000000..e69de29b
--
cgit
From cfce54fe46f7d3db39e50c4113cb9fc74d6719e2 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 24 Dec 2022 18:08:08 -0700
Subject: fix: update parse tests
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../minecraft/mod/tasks/LocalTexturePackParseTask.cpp | 2 +-
launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h | 2 +-
tests/ResourcePackParse_test.cpp | 9 ++++++---
tests/TexturePackParse_test.cpp | 9 ++++++---
.../ResourcePackParse/test_resource_pack_idk.zip | Bin 322 -> 804 bytes
5 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp
index e4492f12..38f1d7c1 100644
--- a/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalTexturePackParseTask.cpp
@@ -116,7 +116,7 @@ bool processZIP(TexturePack& pack, ProcessingLevel level)
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return false;
+ return true;
}
if (zip.setCurrentFile("pack.png")) {
diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
index 44153735..aa5db0c2 100644
--- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
@@ -37,7 +37,7 @@ bool process(WorldSave& save, ProcessingLevel level = ProcessingLevel::Full);
bool processZIP(WorldSave& pack, ProcessingLevel level = ProcessingLevel::Full);
bool processFolder(WorldSave& pack, ProcessingLevel level = ProcessingLevel::Full);
-bool validate(QFileInfo file);
+bool validate(QFileInfo file);
} // namespace WorldSaveUtils
diff --git a/tests/ResourcePackParse_test.cpp b/tests/ResourcePackParse_test.cpp
index 568c3b63..4192da31 100644
--- a/tests/ResourcePackParse_test.cpp
+++ b/tests/ResourcePackParse_test.cpp
@@ -35,10 +35,11 @@ class ResourcePackParseTest : public QObject {
QString zip_rp = FS::PathCombine(source, "test_resource_pack_idk.zip");
ResourcePack pack { QFileInfo(zip_rp) };
- ResourcePackUtils::processZIP(pack);
+ bool valid = ResourcePackUtils::processZIP(pack, ResourcePackUtils::ProcessingLevel::BasicInfoOnly);
QVERIFY(pack.packFormat() == 3);
QVERIFY(pack.description() == "um dois, feijão com arroz, três quatro, feijão no prato, cinco seis, café inglês, sete oito, comer biscoito, nove dez comer pastéis!!");
+ QVERIFY(valid == true);
}
void test_parseFolder()
@@ -48,10 +49,11 @@ class ResourcePackParseTest : public QObject {
QString folder_rp = FS::PathCombine(source, "test_folder");
ResourcePack pack { QFileInfo(folder_rp) };
- ResourcePackUtils::processFolder(pack);
+ bool valid = ResourcePackUtils::processFolder(pack, ResourcePackUtils::ProcessingLevel::BasicInfoOnly);
QVERIFY(pack.packFormat() == 1);
QVERIFY(pack.description() == "Some resource pack maybe");
+ QVERIFY(valid == true);
}
void test_parseFolder2()
@@ -61,10 +63,11 @@ class ResourcePackParseTest : public QObject {
QString folder_rp = FS::PathCombine(source, "another_test_folder");
ResourcePack pack { QFileInfo(folder_rp) };
- ResourcePackUtils::process(pack);
+ bool valid = ResourcePackUtils::process(pack, ResourcePackUtils::ProcessingLevel::BasicInfoOnly);
QVERIFY(pack.packFormat() == 6);
QVERIFY(pack.description() == "o quartel pegou fogo, policia deu sinal, acode acode acode a bandeira nacional");
+ QVERIFY(valid == false);
}
};
diff --git a/tests/TexturePackParse_test.cpp b/tests/TexturePackParse_test.cpp
index 0771f79f..4ddc0a3a 100644
--- a/tests/TexturePackParse_test.cpp
+++ b/tests/TexturePackParse_test.cpp
@@ -36,9 +36,10 @@ class TexturePackParseTest : public QObject {
QString zip_rp = FS::PathCombine(source, "test_texture_pack_idk.zip");
TexturePack pack { QFileInfo(zip_rp) };
- TexturePackUtils::processZIP(pack);
+ bool valid = TexturePackUtils::processZIP(pack);
QVERIFY(pack.description() == "joe biden, wake up");
+ QVERIFY(valid == true);
}
void test_parseFolder()
@@ -48,9 +49,10 @@ class TexturePackParseTest : public QObject {
QString folder_rp = FS::PathCombine(source, "test_texturefolder");
TexturePack pack { QFileInfo(folder_rp) };
- TexturePackUtils::processFolder(pack);
+ bool valid = TexturePackUtils::processFolder(pack, TexturePackUtils::ProcessingLevel::BasicInfoOnly);
QVERIFY(pack.description() == "Some texture pack surely");
+ QVERIFY(valid == true);
}
void test_parseFolder2()
@@ -60,9 +62,10 @@ class TexturePackParseTest : public QObject {
QString folder_rp = FS::PathCombine(source, "another_test_texturefolder");
TexturePack pack { QFileInfo(folder_rp) };
- TexturePackUtils::process(pack);
+ bool valid = TexturePackUtils::process(pack, TexturePackUtils::ProcessingLevel::BasicInfoOnly);
QVERIFY(pack.description() == "quieres\nfor real");
+ QVERIFY(valid == true);
}
};
diff --git a/tests/testdata/ResourcePackParse/test_resource_pack_idk.zip b/tests/testdata/ResourcePackParse/test_resource_pack_idk.zip
index 52b91cdc..b4e66a60 100644
Binary files a/tests/testdata/ResourcePackParse/test_resource_pack_idk.zip and b/tests/testdata/ResourcePackParse/test_resource_pack_idk.zip differ
--
cgit
From 8422e3ac01c861125fd6aea441714a2fb38e5ff9 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 24 Dec 2022 20:38:29 -0700
Subject: feat: zip resource validation check for flame
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/minecraft/mod/DataPack.cpp | 2 +-
launcher/minecraft/mod/ResourcePack.cpp | 2 +-
.../flame/FlameInstanceCreationTask.cpp | 147 ++++++++++++++++-----
.../modplatform/flame/FlameInstanceCreationTask.h | 3 +
4 files changed, 120 insertions(+), 34 deletions(-)
diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp
index 6c333285..ea1d097b 100644
--- a/launcher/minecraft/mod/DataPack.cpp
+++ b/launcher/minecraft/mod/DataPack.cpp
@@ -41,7 +41,7 @@ void DataPack::setPackFormat(int new_format_id)
QMutexLocker locker(&m_data_lock);
if (!s_pack_format_versions.contains(new_format_id)) {
- qWarning() << "Pack format '%1' is not a recognized resource pack id!";
+ qWarning() << "Pack format '" << new_format_id << "' is not a recognized data pack id!";
}
m_pack_format = new_format_id;
diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp
index 47da4fea..87995215 100644
--- a/launcher/minecraft/mod/ResourcePack.cpp
+++ b/launcher/minecraft/mod/ResourcePack.cpp
@@ -27,7 +27,7 @@ void ResourcePack::setPackFormat(int new_format_id)
QMutexLocker locker(&m_data_lock);
if (!s_pack_format_versions.contains(new_format_id)) {
- qWarning() << "Pack format '%1' is not a recognized resource pack id!";
+ qWarning() << "Pack format '" << new_format_id << "' is not a recognized resource pack id!";
}
m_pack_format = new_format_id;
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 1d441f09..2b1bc8d0 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -53,6 +53,13 @@
#include "ui/dialogs/BlockedModsDialog.h"
#include "ui/dialogs/CustomMessageBox.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
const static QMap forgemap = { { "1.2.5", "3.4.9.171" },
{ "1.4.2", "6.0.1.355" },
{ "1.4.7", "6.6.2.534" },
@@ -401,6 +408,11 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
QList blocked_mods;
auto anyBlocked = false;
for (const auto& result : results.files.values()) {
+
+ if(result.fileName.endsWith(".zip")) {
+ m_ZIP_resources.append(std::make_pair(result.fileName, result.targetFolder));
+ }
+
if (!result.resolved || result.url.isEmpty()) {
BlockedMod blocked_mod;
blocked_mod.name = result.fileName;
@@ -439,37 +451,6 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
}
}
-/// @brief copy the matched blocked mods to the instance staging area
-/// @param blocked_mods list of the blocked mods and their matched paths
-void FlameCreationTask::copyBlockedMods(QList const& blocked_mods)
-{
- setStatus(tr("Copying Blocked Mods..."));
- setAbortable(false);
- int i = 0;
- int total = blocked_mods.length();
- setProgress(i, total);
- for (auto const& mod : blocked_mods) {
- if (!mod.matched) {
- qDebug() << mod.name << "was not matched to a local file, skipping copy";
- continue;
- }
-
- auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", mod.targetFolder, mod.name);
-
- setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total)));
-
- qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path;
-
- if (!FS::copy(mod.localPath, dest_path)()) {
- qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed";
- }
-
- i++;
- setProgress(i, total);
- }
-
- setAbortable(true);
-}
void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
{
@@ -509,7 +490,10 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
}
m_mod_id_resolver.reset();
- connect(m_files_job.get(), &NetJob::succeeded, this, [&]() { m_files_job.reset(); });
+ connect(m_files_job.get(), &NetJob::succeeded, this, [&]() {
+ m_files_job.reset();
+ validateZIPResouces();
+ });
connect(m_files_job.get(), &NetJob::failed, [&](QString reason) {
m_files_job.reset();
setError(reason);
@@ -520,3 +504,102 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
setStatus(tr("Downloading mods..."));
m_files_job->start();
}
+
+/// @brief copy the matched blocked mods to the instance staging area
+/// @param blocked_mods list of the blocked mods and their matched paths
+void FlameCreationTask::copyBlockedMods(QList const& blocked_mods)
+{
+ setStatus(tr("Copying Blocked Mods..."));
+ setAbortable(false);
+ int i = 0;
+ int total = blocked_mods.length();
+ setProgress(i, total);
+ for (auto const& mod : blocked_mods) {
+ if (!mod.matched) {
+ qDebug() << mod.name << "was not matched to a local file, skipping copy";
+ continue;
+ }
+
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", mod.targetFolder, mod.name);
+
+ setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total)));
+
+ qDebug() << "Will try to copy" << mod.localPath << "to" << destPath;
+
+ if (!FS::copy(mod.localPath, destPath)()) {
+ qDebug() << "Copy of" << mod.localPath << "to" << destPath << "Failed";
+ }
+
+ i++;
+ setProgress(i, total);
+ }
+
+ setAbortable(true);
+}
+
+static bool moveFile(QString src, QString dst)
+{
+ if (!FS::copy(src, dst)()) { // copy
+ qDebug() << "Copy of" << src << "to" << dst << "Failed!";
+ return false;
+ } else {
+ if (!FS::deletePath(src)) { // remove origonal
+ qDebug() << "Deleation of" << src << "Failed!";
+ return false;
+ };
+ }
+ return true;
+}
+
+void FlameCreationTask::validateZIPResouces()
+{
+ qDebug() << "Validating resoucres stored as .zip are in the right place";
+ for (auto [fileName, targetFolder] : m_ZIP_resources) {
+ qDebug() << "Checking" << fileName << "...";
+ auto localPath = FS::PathCombine(m_stagingPath, "minecraft", targetFolder, fileName);
+ QFileInfo localFileInfo(localPath);
+ if (localFileInfo.exists() && localFileInfo.isFile()) {
+ if (ResourcePackUtils::validate(localFileInfo)) {
+ if (targetFolder != "resourcepacks") {
+ qDebug() << "Target folder of" << fileName << "is incorrect, it's a resource pack.";
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "resourcepacks", fileName);
+ qDebug() << "Moveing" << localPath << "to" << destPath;
+ moveFile(localPath, destPath);
+ } else {
+ qDebug() << fileName << "is in the right place :" << targetFolder;
+ }
+ } else if (TexturePackUtils::validate(localFileInfo)) {
+ if (targetFolder != "texturepacks") {
+ qDebug() << "Target folder of" << fileName << "is incorrect, it's a pre 1.6 texture pack.";
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "texturepacks", fileName);
+ qDebug() << "Moveing" << localPath << "to" << destPath;
+ moveFile(localPath, destPath);
+ } else {
+ qDebug() << fileName << "is in the right place :" << targetFolder;
+ }
+ } else if (DataPackUtils::validate(localFileInfo)) {
+ if (targetFolder != "datapacks") {
+ qDebug() << "Target folder of" << fileName << "is incorrect, it's a data pack.";
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "datapacks", fileName);
+ qDebug() << "Moveing" << localPath << "to" << destPath;
+ moveFile(localPath, destPath);
+ } else {
+ qDebug() << fileName << "is in the right place :" << targetFolder;
+ }
+ } else if (ModUtils::validate(localFileInfo)) {
+ if (targetFolder != "mods") {
+ qDebug() << "Target folder of" << fileName << "is incorrect, it's a mod.";
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "mods", fileName);
+ qDebug() << "Moveing" << localPath << "to" << destPath;
+ moveFile(localPath, destPath);
+ } else {
+ qDebug() << fileName << "is in the right place :" << targetFolder;
+ }
+ } else {
+ qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is.";
+ }
+ } else {
+ qDebug() << "Can't find" << localPath << "to validate it, ignoreing";
+ }
+ }
+}
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h
index 3a1c729f..498e1d6e 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.h
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h
@@ -77,6 +77,7 @@ class FlameCreationTask final : public InstanceCreationTask {
void idResolverSucceeded(QEventLoop&);
void setupDownloadJob(QEventLoop&);
void copyBlockedMods(QList const& blocked_mods);
+ void validateZIPResouces();
private:
QWidget* m_parent = nullptr;
@@ -90,5 +91,7 @@ class FlameCreationTask final : public InstanceCreationTask {
QString m_managed_id, m_managed_version_id;
+ QList> m_ZIP_resources;
+
std::optional m_instance;
};
--
cgit
From 78984eea3aa398451dc511712ccb7ec55f93194c Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sun, 25 Dec 2022 16:49:56 -0700
Subject: feat: support installing worlds during flame pack import.
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../flame/FlameInstanceCreationTask.cpp | 72 ++++++++++++----------
1 file changed, 39 insertions(+), 33 deletions(-)
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 2b1bc8d0..204d5c1f 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -57,6 +57,9 @@
#include
#include
#include
+#include
+#include
+#include
#include
#include
@@ -537,13 +540,13 @@ void FlameCreationTask::copyBlockedMods(QList const& blocked_mods)
setAbortable(true);
}
-static bool moveFile(QString src, QString dst)
+bool moveFile(QString src, QString dst)
{
if (!FS::copy(src, dst)()) { // copy
qDebug() << "Copy of" << src << "to" << dst << "Failed!";
return false;
} else {
- if (!FS::deletePath(src)) { // remove origonal
+ if (!FS::deletePath(src)) { // remove original
qDebug() << "Deleation of" << src << "Failed!";
return false;
};
@@ -551,50 +554,53 @@ static bool moveFile(QString src, QString dst)
return true;
}
+
void FlameCreationTask::validateZIPResouces()
{
qDebug() << "Validating resoucres stored as .zip are in the right place";
for (auto [fileName, targetFolder] : m_ZIP_resources) {
+
qDebug() << "Checking" << fileName << "...";
auto localPath = FS::PathCombine(m_stagingPath, "minecraft", targetFolder, fileName);
+
+ auto validatePath = [&localPath, this](QString fileName, QString targetFolder, QString realTarget) {
+ if (targetFolder != "resourcepacks") {
+ qDebug() << "Target folder of" << fileName << "is incorrect, it's a resource pack.";
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "resourcepacks", fileName);
+ qDebug() << "Moving" << localPath << "to" << destPath;
+ if (moveFile(localPath, destPath)) {
+ return destPath;
+ }
+ } else {
+ qDebug() << fileName << "is in the right place :" << targetFolder;
+ }
+ return localPath;
+ };
+
QFileInfo localFileInfo(localPath);
if (localFileInfo.exists() && localFileInfo.isFile()) {
if (ResourcePackUtils::validate(localFileInfo)) {
- if (targetFolder != "resourcepacks") {
- qDebug() << "Target folder of" << fileName << "is incorrect, it's a resource pack.";
- auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "resourcepacks", fileName);
- qDebug() << "Moveing" << localPath << "to" << destPath;
- moveFile(localPath, destPath);
- } else {
- qDebug() << fileName << "is in the right place :" << targetFolder;
- }
+ validatePath(fileName, targetFolder, "resourcepacks");
} else if (TexturePackUtils::validate(localFileInfo)) {
- if (targetFolder != "texturepacks") {
- qDebug() << "Target folder of" << fileName << "is incorrect, it's a pre 1.6 texture pack.";
- auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "texturepacks", fileName);
- qDebug() << "Moveing" << localPath << "to" << destPath;
- moveFile(localPath, destPath);
- } else {
- qDebug() << fileName << "is in the right place :" << targetFolder;
- }
+ validatePath(fileName, targetFolder, "texturepacks");
} else if (DataPackUtils::validate(localFileInfo)) {
- if (targetFolder != "datapacks") {
- qDebug() << "Target folder of" << fileName << "is incorrect, it's a data pack.";
- auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "datapacks", fileName);
- qDebug() << "Moveing" << localPath << "to" << destPath;
- moveFile(localPath, destPath);
- } else {
- qDebug() << fileName << "is in the right place :" << targetFolder;
- }
+ validatePath(fileName, targetFolder, "datapacks");
} else if (ModUtils::validate(localFileInfo)) {
- if (targetFolder != "mods") {
- qDebug() << "Target folder of" << fileName << "is incorrect, it's a mod.";
- auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "mods", fileName);
- qDebug() << "Moveing" << localPath << "to" << destPath;
- moveFile(localPath, destPath);
+ validatePath(fileName, targetFolder, "mods");
+ } else if (WorldSaveUtils::validate(localFileInfo)) {
+ QString worldPath = validatePath(fileName, targetFolder, "saves");
+
+ qDebug() << "Installing World from" << worldPath;
+ World w(worldPath);
+ if (!w.isValid()) {
+ qDebug() << "World at" << worldPath << "is not valid, skipping install.";
} else {
- qDebug() << fileName << "is in the right place :" << targetFolder;
- }
+ w.install(FS::PathCombine(m_stagingPath, "minecraft", "saves"));
+ }
+ } else if (ShaderPackUtils::validate(localFileInfo)) {
+ // in theroy flame API can't do this but who knows, that *may* change ?
+ // better to handle it if it *does* occure in the future
+ validatePath(fileName, targetFolder, "shaderpacks");
} else {
qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is.";
}
--
cgit
From b2082bfde7149a5596fe8a467659699ad569f932 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sun, 25 Dec 2022 17:16:26 -0700
Subject: fix: explicit QFileInfo converison for qt6 fix: validatePath in
validateZIPResouces
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../modplatform/flame/FlameInstanceCreationTask.cpp | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 204d5c1f..b62d05ab 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -564,15 +564,13 @@ void FlameCreationTask::validateZIPResouces()
auto localPath = FS::PathCombine(m_stagingPath, "minecraft", targetFolder, fileName);
auto validatePath = [&localPath, this](QString fileName, QString targetFolder, QString realTarget) {
- if (targetFolder != "resourcepacks") {
- qDebug() << "Target folder of" << fileName << "is incorrect, it's a resource pack.";
- auto destPath = FS::PathCombine(m_stagingPath, "minecraft", "resourcepacks", fileName);
+ if (targetFolder != realTarget) {
+ qDebug() << "Target folder of" << fileName << "is incorrect, it belongs in" << realTarget;
+ auto destPath = FS::PathCombine(m_stagingPath, "minecraft", realTarget, fileName);
qDebug() << "Moving" << localPath << "to" << destPath;
if (moveFile(localPath, destPath)) {
return destPath;
}
- } else {
- qDebug() << fileName << "is in the right place :" << targetFolder;
}
return localPath;
};
@@ -580,18 +578,24 @@ void FlameCreationTask::validateZIPResouces()
QFileInfo localFileInfo(localPath);
if (localFileInfo.exists() && localFileInfo.isFile()) {
if (ResourcePackUtils::validate(localFileInfo)) {
+ qDebug() << fileName << "is a resource pack";
validatePath(fileName, targetFolder, "resourcepacks");
} else if (TexturePackUtils::validate(localFileInfo)) {
+ qDebug() << fileName << "is a pre 1.6 texture pack";
validatePath(fileName, targetFolder, "texturepacks");
} else if (DataPackUtils::validate(localFileInfo)) {
+ qDebug() << fileName << "is a data pack";
validatePath(fileName, targetFolder, "datapacks");
} else if (ModUtils::validate(localFileInfo)) {
+ qDebug() << fileName << "is a mod";
validatePath(fileName, targetFolder, "mods");
} else if (WorldSaveUtils::validate(localFileInfo)) {
+ qDebug() << fileName << "is a world save";
QString worldPath = validatePath(fileName, targetFolder, "saves");
qDebug() << "Installing World from" << worldPath;
- World w(worldPath);
+ QFileInfo worldFileInfo(worldPath);
+ World w(worldFileInfo);
if (!w.isValid()) {
qDebug() << "World at" << worldPath << "is not valid, skipping install.";
} else {
@@ -600,6 +604,7 @@ void FlameCreationTask::validateZIPResouces()
} else if (ShaderPackUtils::validate(localFileInfo)) {
// in theroy flame API can't do this but who knows, that *may* change ?
// better to handle it if it *does* occure in the future
+ qDebug() << fileName << "is a shader pack";
validatePath(fileName, targetFolder, "shaderpacks");
} else {
qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is.";
--
cgit
From 3691f3a2963c77dbd7b469b4b90ca79b61014d43 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Mon, 26 Dec 2022 14:29:13 -0700
Subject: fix: cleanup and suggested changes
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/minecraft/mod/DataPack.cpp | 6 +--
launcher/minecraft/mod/DataPack.h | 8 +--
launcher/minecraft/mod/Mod.cpp | 2 +-
launcher/minecraft/mod/ResourcePack.cpp | 11 ++--
launcher/minecraft/mod/ShaderPack.cpp | 2 -
launcher/minecraft/mod/ShaderPack.h | 24 ++++-----
launcher/minecraft/mod/WorldSave.cpp | 6 +--
launcher/minecraft/mod/WorldSave.h | 14 ++---
.../minecraft/mod/tasks/LocalDataPackParseTask.cpp | 46 ++++++++++-------
.../minecraft/mod/tasks/LocalDataPackParseTask.h | 2 +-
launcher/minecraft/mod/tasks/LocalModParseTask.cpp | 36 ++++++-------
launcher/minecraft/mod/tasks/LocalModParseTask.h | 15 +++---
.../mod/tasks/LocalResourcePackParseTask.cpp | 60 ++++++++++++++--------
.../mod/tasks/LocalShaderPackParseTask.cpp | 23 ++++-----
.../minecraft/mod/tasks/LocalShaderPackParseTask.h | 3 +-
.../mod/tasks/LocalWorldSaveParseTask.cpp | 56 +++++++++++---------
.../minecraft/mod/tasks/LocalWorldSaveParseTask.h | 2 +-
.../flame/FlameInstanceCreationTask.cpp | 43 ++++++++--------
tests/ResourcePackParse_test.cpp | 2 +-
19 files changed, 187 insertions(+), 174 deletions(-)
diff --git a/launcher/minecraft/mod/DataPack.cpp b/launcher/minecraft/mod/DataPack.cpp
index ea1d097b..5c58f6b2 100644
--- a/launcher/minecraft/mod/DataPack.cpp
+++ b/launcher/minecraft/mod/DataPack.cpp
@@ -30,9 +30,9 @@
// Values taken from:
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_data_pack#%22pack_format%22
static const QMap> s_pack_format_versions = {
- { 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.1") } }, { 9, { Version("1.18.2"), Version("1.18.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.1") } }, { 9, { Version("1.18.2"), Version("1.18.2") } },
{ 10, { Version("1.19"), Version("1.19.3") } },
};
diff --git a/launcher/minecraft/mod/DataPack.h b/launcher/minecraft/mod/DataPack.h
index 17d9b65e..fc2703c7 100644
--- a/launcher/minecraft/mod/DataPack.h
+++ b/launcher/minecraft/mod/DataPack.h
@@ -45,7 +45,7 @@ class DataPack : public Resource {
/** Gets, respectively, the lower and upper versions supported by the set pack format. */
[[nodiscard]] std::pair compatibleVersions() const;
- /** Gets the description of the resource pack. */
+ /** Gets the description of the data pack. */
[[nodiscard]] QString description() const { return m_description; }
/** Thread-safe. */
@@ -62,12 +62,12 @@ class DataPack : public Resource {
protected:
mutable QMutex m_data_lock;
- /* The 'version' of a resource pack, as defined in the pack.mcmeta file.
- * See https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+ /* The 'version' of a data pack, as defined in the pack.mcmeta file.
+ * See https://minecraft.fandom.com/wiki/Data_pack#pack.mcmeta
*/
int m_pack_format = 0;
- /** The resource pack's description, as defined in the pack.mcmeta file.
+ /** The data pack's description, as defined in the pack.mcmeta file.
*/
QString m_description;
};
diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp
index 8b00354d..3439b6ee 100644
--- a/launcher/minecraft/mod/Mod.cpp
+++ b/launcher/minecraft/mod/Mod.cpp
@@ -199,4 +199,4 @@ void Mod::finishResolvingWithDetails(ModDetails&& details)
bool Mod::valid() const
{
return !m_local_details.mod_id.isEmpty();
-}
\ No newline at end of file
+}
diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp
index 87995215..876d5c3e 100644
--- a/launcher/minecraft/mod/ResourcePack.cpp
+++ b/launcher/minecraft/mod/ResourcePack.cpp
@@ -13,12 +13,11 @@
// Values taken from:
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
static const QMap> s_pack_format_versions = {
- { 1, { Version("1.6.1"), Version("1.8.9") } }, { 2, { Version("1.9"), Version("1.10.2") } },
- { 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") } },
- // { 11, { Version("22w42a"), Version("22w44a") } }
+ { 1, { Version("1.6.1"), Version("1.8.9") } }, { 2, { Version("1.9"), Version("1.10.2") } },
+ { 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") } }, { 11, { Version("22w42a"), Version("22w44a") } },
{ 12, { Version("1.19.3"), Version("1.19.3") } },
};
diff --git a/launcher/minecraft/mod/ShaderPack.cpp b/launcher/minecraft/mod/ShaderPack.cpp
index b8d427c7..6a9641de 100644
--- a/launcher/minecraft/mod/ShaderPack.cpp
+++ b/launcher/minecraft/mod/ShaderPack.cpp
@@ -24,12 +24,10 @@
#include "minecraft/mod/tasks/LocalShaderPackParseTask.h"
-
void ShaderPack::setPackFormat(ShaderPackFormat new_format)
{
QMutexLocker locker(&m_data_lock);
-
m_pack_format = new_format;
}
diff --git a/launcher/minecraft/mod/ShaderPack.h b/launcher/minecraft/mod/ShaderPack.h
index a0dad7a1..ec0f9404 100644
--- a/launcher/minecraft/mod/ShaderPack.h
+++ b/launcher/minecraft/mod/ShaderPack.h
@@ -24,31 +24,27 @@
#include "Resource.h"
/* Info:
- * Currently For Optifine / Iris shader packs,
- * could be expanded to support others should they exsist?
+ * Currently For Optifine / Iris shader packs,
+ * could be expanded to support others should they exist?
*
- * This class and enum are mostly here as placeholders for validating
- * that a shaderpack exsists and is in the right format,
+ * This class and enum are mostly here as placeholders for validating
+ * that a shaderpack exists and is in the right format,
* namely that they contain a folder named 'shaders'.
*
- * In the technical sense it would be possible to parse files like `shaders/shaders.properties`
- * to get information like the availble profiles but this is not all that usefull without more knoledge of the
- * shader mod used to be able to change settings
- *
+ * In the technical sense it would be possible to parse files like `shaders/shaders.properties`
+ * to get information like the available profiles but this is not all that useful without more knowledge of the
+ * shader mod used to be able to change settings.
*/
#include
-enum class ShaderPackFormat {
- VALID,
- INVALID
-};
+enum class ShaderPackFormat { VALID, INVALID };
class ShaderPack : public Resource {
Q_OBJECT
public:
using Ptr = shared_qobject_ptr;
-
+
[[nodiscard]] ShaderPackFormat packFormat() const { return m_pack_format; }
ShaderPack(QObject* parent = nullptr) : Resource(parent) {}
@@ -62,5 +58,5 @@ class ShaderPack : public Resource {
protected:
mutable QMutex m_data_lock;
- ShaderPackFormat m_pack_format = ShaderPackFormat::INVALID;
+ ShaderPackFormat m_pack_format = ShaderPackFormat::INVALID;
};
diff --git a/launcher/minecraft/mod/WorldSave.cpp b/launcher/minecraft/mod/WorldSave.cpp
index 9a626fc1..7123f512 100644
--- a/launcher/minecraft/mod/WorldSave.cpp
+++ b/launcher/minecraft/mod/WorldSave.cpp
@@ -27,7 +27,6 @@ void WorldSave::setSaveFormat(WorldSaveFormat new_save_format)
{
QMutexLocker locker(&m_data_lock);
-
m_save_format = new_save_format;
}
@@ -35,11 +34,10 @@ void WorldSave::setSaveDirName(QString dir_name)
{
QMutexLocker locker(&m_data_lock);
-
m_save_dir_name = dir_name;
}
bool WorldSave::valid() const
{
- return m_save_format != WorldSaveFormat::INVALID;
-}
\ No newline at end of file
+ return m_save_format != WorldSaveFormat::INVALID;
+}
diff --git a/launcher/minecraft/mod/WorldSave.h b/launcher/minecraft/mod/WorldSave.h
index f703f34c..5985fc8a 100644
--- a/launcher/minecraft/mod/WorldSave.h
+++ b/launcher/minecraft/mod/WorldSave.h
@@ -27,11 +27,7 @@
class Version;
-enum class WorldSaveFormat {
- SINGLE,
- MULTI,
- INVALID
-};
+enum class WorldSaveFormat { SINGLE, MULTI, INVALID };
class WorldSave : public Resource {
Q_OBJECT
@@ -53,15 +49,13 @@ class WorldSave : public Resource {
bool valid() const override;
-
protected:
mutable QMutex m_data_lock;
- /* The 'version' of a resource pack, as defined in the pack.mcmeta file.
- * See https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+ /** The format in which the save file is in.
+ * Since saves can be distributed in various slightly different ways, this allows us to treat them separately.
*/
WorldSaveFormat m_save_format = WorldSaveFormat::INVALID;
- QString m_save_dir_name;
-
+ QString m_save_dir_name;
};
diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp
index 8bc8278b..3fcb2110 100644
--- a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.cpp
@@ -25,8 +25,8 @@
#include "Json.h"
#include
-#include
#include
+#include
#include
@@ -40,7 +40,7 @@ bool process(DataPack& pack, ProcessingLevel level)
case ResourceType::ZIPFILE:
return DataPackUtils::processZIP(pack, level);
default:
- qWarning() << "Invalid type for resource pack parse task!";
+ qWarning() << "Invalid type for data pack parse task!";
return false;
}
}
@@ -49,11 +49,16 @@ bool processFolder(DataPack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::FOLDER);
+ auto mcmeta_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.mcmeta";
+ return false; // the mcmeta is not optional
+ };
+
QFileInfo mcmeta_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.mcmeta"));
if (mcmeta_file_info.exists() && mcmeta_file_info.isFile()) {
QFile mcmeta_file(mcmeta_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
- return false; // can't open mcmeta file
+ return mcmeta_invalid(); // can't open mcmeta file
auto data = mcmeta_file.readAll();
@@ -61,22 +66,22 @@ bool processFolder(DataPack& pack, ProcessingLevel level)
mcmeta_file.close();
if (!mcmeta_result) {
- return false; // mcmeta invalid
+ return mcmeta_invalid(); // mcmeta invalid
}
} else {
- return false; // mcmeta file isn't a valid file
+ return mcmeta_invalid(); // mcmeta file isn't a valid file
}
QFileInfo data_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "data"));
if (!data_dir_info.exists() || !data_dir_info.isDir()) {
- return false; // data dir does not exists or isn't valid
+ return false; // data dir does not exists or isn't valid
}
if (level == ProcessingLevel::BasicInfoOnly) {
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
- return true; // all tests passed
+ return true; // all tests passed
}
bool processZIP(DataPack& pack, ProcessingLevel level)
@@ -85,15 +90,20 @@ bool processZIP(DataPack& pack, ProcessingLevel level)
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return false; // can't open zip file
+ return false; // can't open zip file
QuaZipFile file(&zip);
+ auto mcmeta_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.mcmeta";
+ return false; // the mcmeta is not optional
+ };
+
if (zip.setCurrentFile("pack.mcmeta")) {
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return false;
+ return mcmeta_invalid();
}
auto data = file.readAll();
@@ -102,20 +112,20 @@ bool processZIP(DataPack& pack, ProcessingLevel level)
file.close();
if (!mcmeta_result) {
- return false; // mcmeta invalid
+ return mcmeta_invalid(); // mcmeta invalid
}
} else {
- return false; // could not set pack.mcmeta as current file.
+ return mcmeta_invalid(); // could not set pack.mcmeta as current file.
}
QuaZipDir zipDir(&zip);
if (!zipDir.exists("/data")) {
- return false; // data dir does not exists at zip root
+ return false; // data dir does not exists at zip root
}
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
zip.close();
@@ -123,7 +133,7 @@ bool processZIP(DataPack& pack, ProcessingLevel level)
return true;
}
-// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
+// https://minecraft.fandom.com/wiki/Data_pack#pack.mcmeta
bool processMCMeta(DataPack& pack, QByteArray&& raw_data)
{
try {
@@ -147,9 +157,7 @@ bool validate(QFileInfo file)
} // namespace DataPackUtils
-LocalDataPackParseTask::LocalDataPackParseTask(int token, DataPack& dp)
- : Task(nullptr, false), m_token(token), m_resource_pack(dp)
-{}
+LocalDataPackParseTask::LocalDataPackParseTask(int token, DataPack& dp) : Task(nullptr, false), m_token(token), m_data_pack(dp) {}
bool LocalDataPackParseTask::abort()
{
@@ -159,7 +167,7 @@ bool LocalDataPackParseTask::abort()
void LocalDataPackParseTask::executeTask()
{
- if (!DataPackUtils::process(m_resource_pack))
+ if (!DataPackUtils::process(m_data_pack))
return;
if (m_aborted)
diff --git a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
index 54e3d398..12fd8c82 100644
--- a/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalDataPackParseTask.h
@@ -59,7 +59,7 @@ class LocalDataPackParseTask : public Task {
private:
int m_token;
- DataPack& m_resource_pack;
+ DataPack& m_data_pack;
bool m_aborted = false;
};
diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
index e8fd39b6..8bfe2c84 100644
--- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp
@@ -284,7 +284,8 @@ ModDetails ReadLiteModInfo(QByteArray contents)
return details;
}
-bool process(Mod& mod, ProcessingLevel level) {
+bool process(Mod& mod, ProcessingLevel level)
+{
switch (mod.type()) {
case ResourceType::FOLDER:
return processFolder(mod, level);
@@ -293,13 +294,13 @@ bool process(Mod& mod, ProcessingLevel level) {
case ResourceType::LITEMOD:
return processLitemod(mod);
default:
- qWarning() << "Invalid type for resource pack parse task!";
+ qWarning() << "Invalid type for mod parse task!";
return false;
}
}
-bool processZIP(Mod& mod, ProcessingLevel level) {
-
+bool processZIP(Mod& mod, ProcessingLevel level)
+{
ModDetails details;
QuaZip zip(mod.fileinfo().filePath());
@@ -316,7 +317,7 @@ bool processZIP(Mod& mod, ProcessingLevel level) {
details = ReadMCModTOML(file.readAll());
file.close();
-
+
// to replace ${file.jarVersion} with the actual version, as needed
if (details.version == "${file.jarVersion}") {
if (zip.setCurrentFile("META-INF/MANIFEST.MF")) {
@@ -347,7 +348,6 @@ bool processZIP(Mod& mod, ProcessingLevel level) {
}
}
-
zip.close();
mod.setDetails(details);
@@ -403,11 +403,11 @@ bool processZIP(Mod& mod, ProcessingLevel level) {
}
zip.close();
- return false; // no valid mod found in archive
+ return false; // no valid mod found in archive
}
-bool processFolder(Mod& mod, ProcessingLevel level) {
-
+bool processFolder(Mod& mod, ProcessingLevel level)
+{
ModDetails details;
QFileInfo mcmod_info(FS::PathCombine(mod.fileinfo().filePath(), "mcmod.info"));
@@ -424,13 +424,13 @@ bool processFolder(Mod& mod, ProcessingLevel level) {
return true;
}
- return false; // no valid mcmod.info file found
+ return false; // no valid mcmod.info file found
}
-bool processLitemod(Mod& mod, ProcessingLevel level) {
-
+bool processLitemod(Mod& mod, ProcessingLevel level)
+{
ModDetails details;
-
+
QuaZip zip(mod.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
return false;
@@ -451,24 +451,22 @@ bool processLitemod(Mod& mod, ProcessingLevel level) {
}
zip.close();
- return false; // no valid litemod.json found in archive
+ return false; // no valid litemod.json found in archive
}
/** Checks whether a file is valid as a mod or not. */
-bool validate(QFileInfo file) {
-
+bool validate(QFileInfo file)
+{
Mod mod{ file };
return ModUtils::process(mod, ProcessingLevel::BasicInfoOnly) && mod.valid();
}
} // namespace ModUtils
-
LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile)
: Task(nullptr, false), m_token(token), m_type(type), m_modFile(modFile), m_result(new Result())
{}
-
bool LocalModParseTask::abort()
{
m_aborted.store(true);
@@ -476,7 +474,7 @@ bool LocalModParseTask::abort()
}
void LocalModParseTask::executeTask()
-{
+{
Mod mod{ m_modFile };
ModUtils::process(mod, ModUtils::ProcessingLevel::Full);
diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.h b/launcher/minecraft/mod/tasks/LocalModParseTask.h
index c9512166..38dae135 100644
--- a/launcher/minecraft/mod/tasks/LocalModParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalModParseTask.h
@@ -27,32 +27,29 @@ bool processLitemod(Mod& mod, ProcessingLevel level = ProcessingLevel::Full);
bool validate(QFileInfo file);
} // namespace ModUtils
-class LocalModParseTask : public Task
-{
+class LocalModParseTask : public Task {
Q_OBJECT
-public:
+ public:
struct Result {
ModDetails details;
};
using ResultPtr = std::shared_ptr;
- ResultPtr result() const {
- return m_result;
- }
+ ResultPtr result() const { return m_result; }
[[nodiscard]] bool canAbort() const override { return true; }
bool abort() override;
- LocalModParseTask(int token, ResourceType type, const QFileInfo & modFile);
+ LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile);
void executeTask() override;
[[nodiscard]] int token() const { return m_token; }
-private:
+ private:
void processAsZip();
void processAsFolder();
void processAsLitemod();
-private:
+ private:
int m_token;
ResourceType m_type;
QFileInfo m_modFile;
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
index 2c41c9ae..4bf0b80d 100644
--- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
@@ -22,8 +22,8 @@
#include "Json.h"
#include
-#include
#include
+#include
#include
@@ -46,11 +46,16 @@ bool processFolder(ResourcePack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::FOLDER);
+ auto mcmeta_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.mcmeta";
+ return false; // the mcmeta is not optional
+ };
+
QFileInfo mcmeta_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.mcmeta"));
if (mcmeta_file_info.exists() && mcmeta_file_info.isFile()) {
QFile mcmeta_file(mcmeta_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
- return false; // can't open mcmeta file
+ return mcmeta_invalid(); // can't open mcmeta file
auto data = mcmeta_file.readAll();
@@ -58,26 +63,31 @@ bool processFolder(ResourcePack& pack, ProcessingLevel level)
mcmeta_file.close();
if (!mcmeta_result) {
- return false; // mcmeta invalid
+ return mcmeta_invalid(); // mcmeta invalid
}
} else {
- return false; // mcmeta file isn't a valid file
+ return mcmeta_invalid(); // mcmeta file isn't a valid file
}
QFileInfo assets_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "assets"));
if (!assets_dir_info.exists() || !assets_dir_info.isDir()) {
- return false; // assets dir does not exists or isn't valid
+ return false; // assets dir does not exists or isn't valid
}
if (level == ProcessingLevel::BasicInfoOnly) {
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
-
+
+ auto png_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png";
+ return true; // the png is optional
+ };
+
QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
if (image_file_info.exists() && image_file_info.isFile()) {
QFile pack_png_file(image_file_info.filePath());
if (!pack_png_file.open(QIODevice::ReadOnly))
- return false; // can't open pack.png file
+ return png_invalid(); // can't open pack.png file
auto data = pack_png_file.readAll();
@@ -85,13 +95,13 @@ bool processFolder(ResourcePack& pack, ProcessingLevel level)
pack_png_file.close();
if (!pack_png_result) {
- return false; // pack.png invalid
+ return png_invalid(); // pack.png invalid
}
} else {
- return false; // pack.png does not exists or is not a valid file.
+ return png_invalid(); // pack.png does not exists or is not a valid file.
}
- return true; // all tests passed
+ return true; // all tests passed
}
bool processZIP(ResourcePack& pack, ProcessingLevel level)
@@ -100,15 +110,20 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level)
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return false; // can't open zip file
+ return false; // can't open zip file
QuaZipFile file(&zip);
+ auto mcmeta_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.mcmeta";
+ return false; // the mcmeta is not optional
+ };
+
if (zip.setCurrentFile("pack.mcmeta")) {
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return false;
+ return mcmeta_invalid();
}
auto data = file.readAll();
@@ -117,27 +132,32 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level)
file.close();
if (!mcmeta_result) {
- return false; // mcmeta invalid
+ return mcmeta_invalid(); // mcmeta invalid
}
} else {
- return false; // could not set pack.mcmeta as current file.
+ return mcmeta_invalid(); // could not set pack.mcmeta as current file.
}
QuaZipDir zipDir(&zip);
if (!zipDir.exists("/assets")) {
- return false; // assets dir does not exists at zip root
+ return false; // assets dir does not exists at zip root
}
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
+ auto png_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png";
+ return true; // the png is optional
+ };
+
if (zip.setCurrentFile("pack.png")) {
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file in zip.";
zip.close();
- return false;
+ return png_invalid();
}
auto data = file.readAll();
@@ -146,10 +166,10 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level)
file.close();
if (!pack_png_result) {
- return false; // pack.png invalid
+ return png_invalid(); // pack.png invalid
}
} else {
- return false; // could not set pack.mcmeta as current file.
+ return png_invalid(); // could not set pack.mcmeta as current file.
}
zip.close();
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
index 088853b9..a9949735 100644
--- a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
@@ -24,8 +24,8 @@
#include "FileSystem.h"
#include
-#include
#include
+#include
namespace ShaderPackUtils {
@@ -45,18 +45,18 @@ bool process(ShaderPack& pack, ProcessingLevel level)
bool processFolder(ShaderPack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::FOLDER);
-
+
QFileInfo shaders_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "shaders"));
if (!shaders_dir_info.exists() || !shaders_dir_info.isDir()) {
- return false; // assets dir does not exists or isn't valid
+ return false; // assets dir does not exists or isn't valid
}
pack.setPackFormat(ShaderPackFormat::VALID);
if (level == ProcessingLevel::BasicInfoOnly) {
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
-
- return true; // all tests passed
+
+ return true; // all tests passed
}
bool processZIP(ShaderPack& pack, ProcessingLevel level)
@@ -65,19 +65,19 @@ bool processZIP(ShaderPack& pack, ProcessingLevel level)
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return false; // can't open zip file
+ return false; // can't open zip file
QuaZipFile file(&zip);
QuaZipDir zipDir(&zip);
if (!zipDir.exists("/shaders")) {
- return false; // assets dir does not exists at zip root
+ return false; // assets dir does not exists at zip root
}
pack.setPackFormat(ShaderPackFormat::VALID);
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
zip.close();
@@ -85,7 +85,6 @@ bool processZIP(ShaderPack& pack, ProcessingLevel level)
return true;
}
-
bool validate(QFileInfo file)
{
ShaderPack sp{ file };
@@ -94,9 +93,7 @@ bool validate(QFileInfo file)
} // namespace ShaderPackUtils
-LocalShaderPackParseTask::LocalShaderPackParseTask(int token, ShaderPack& sp)
- : Task(nullptr, false), m_token(token), m_shader_pack(sp)
-{}
+LocalShaderPackParseTask::LocalShaderPackParseTask(int token, ShaderPack& sp) : Task(nullptr, false), m_token(token), m_shader_pack(sp) {}
bool LocalShaderPackParseTask::abort()
{
diff --git a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
index 5d113508..6be2183c 100644
--- a/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
@@ -19,7 +19,6 @@
* along with this program. If not, see .
*/
-
#pragma once
#include
@@ -38,7 +37,7 @@ bool process(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
bool processZIP(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
bool processFolder(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
-/** Checks whether a file is valid as a resource pack or not. */
+/** Checks whether a file is valid as a shader pack or not. */
bool validate(QFileInfo file);
} // namespace ShaderPackUtils
diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
index b7f2420a..cbc8f8ce 100644
--- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
@@ -24,12 +24,12 @@
#include "FileSystem.h"
-#include
-#include
#include
-#include
#include
-#include
+#include
+
+#include
+#include
namespace WorldSaveUtils {
@@ -41,15 +41,22 @@ bool process(WorldSave& pack, ProcessingLevel level)
case ResourceType::ZIPFILE:
return WorldSaveUtils::processZIP(pack, level);
default:
- qWarning() << "Invalid type for shader pack parse task!";
+ qWarning() << "Invalid type for world save parse task!";
return false;
}
}
-
+/// @brief checks a folder structure to see if it contains a level.dat
+/// @param dir the path to check
+/// @param saves used in recursive call if a "saves" dir was found
+/// @return std::tuple of (
+/// bool ,
+/// QString ,
+/// bool
+/// )
static std::tuple contains_level_dat(QDir dir, bool saves = false)
{
- for(auto const& entry : dir.entryInfoList()) {
+ for (auto const& entry : dir.entryInfoList()) {
if (!entry.isDir()) {
continue;
}
@@ -64,12 +71,11 @@ static std::tuple contains_level_dat(QDir dir, bool saves =
return std::make_tuple(false, "", saves);
}
-
bool processFolder(WorldSave& save, ProcessingLevel level)
{
Q_ASSERT(save.type() == ResourceType::FOLDER);
- auto [ found, save_dir_name, found_saves_dir ] = contains_level_dat(QDir(save.fileinfo().filePath()));
+ auto [found, save_dir_name, found_saves_dir] = contains_level_dat(QDir(save.fileinfo().filePath()));
if (!found) {
return false;
@@ -84,14 +90,21 @@ bool processFolder(WorldSave& save, ProcessingLevel level)
}
if (level == ProcessingLevel::BasicInfoOnly) {
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
- // resurved for more intensive processing
-
- return true; // all tests passed
+ // reserved for more intensive processing
+
+ return true; // all tests passed
}
+/// @brief checks a folder structure to see if it contains a level.dat
+/// @param zip the zip file to check
+/// @return std::tuple of (
+/// bool ,
+/// QString ,
+/// bool
+/// )
static std::tuple contains_level_dat(QuaZip& zip)
{
bool saves = false;
@@ -100,7 +113,7 @@ static std::tuple contains_level_dat(QuaZip& zip)
saves = true;
zipDir.cd("/saves");
}
-
+
for (auto const& entry : zipDir.entryList()) {
zipDir.cd(entry);
if (zipDir.exists("level.dat")) {
@@ -117,14 +130,14 @@ bool processZIP(WorldSave& save, ProcessingLevel level)
QuaZip zip(save.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
- return false; // can't open zip file
+ return false; // can't open zip file
- auto [ found, save_dir_name, found_saves_dir ] = contains_level_dat(zip);
+ auto [found, save_dir_name, found_saves_dir] = contains_level_dat(zip);
if (save_dir_name.endsWith("/")) {
save_dir_name.chop(1);
}
-
+
if (!found) {
return false;
}
@@ -139,17 +152,16 @@ bool processZIP(WorldSave& save, ProcessingLevel level)
if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
- return true; // only need basic info already checked
+ return true; // only need basic info already checked
}
- // resurved for more intensive processing
+ // reserved for more intensive processing
zip.close();
return true;
}
-
bool validate(QFileInfo file)
{
WorldSave sp{ file };
@@ -158,9 +170,7 @@ bool validate(QFileInfo file)
} // namespace WorldSaveUtils
-LocalWorldSaveParseTask::LocalWorldSaveParseTask(int token, WorldSave& save)
- : Task(nullptr, false), m_token(token), m_save(save)
-{}
+LocalWorldSaveParseTask::LocalWorldSaveParseTask(int token, WorldSave& save) : Task(nullptr, false), m_token(token), m_save(save) {}
bool LocalWorldSaveParseTask::abort()
{
diff --git a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
index aa5db0c2..9dcdca2b 100644
--- a/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalWorldSaveParseTask.h
@@ -59,4 +59,4 @@ class LocalWorldSaveParseTask : public Task {
WorldSave& m_save;
bool m_aborted = false;
-};
\ No newline at end of file
+};
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index b62d05ab..79104e17 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -53,15 +53,16 @@
#include "ui/dialogs/BlockedModsDialog.h"
#include "ui/dialogs/CustomMessageBox.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+#include
+#include
+
+#include "minecraft/World.h"
+#include "minecraft/mod/tasks/LocalDataPackParseTask.h"
+#include "minecraft/mod/tasks/LocalModParseTask.h"
+#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
+#include "minecraft/mod/tasks/LocalShaderPackParseTask.h"
+#include "minecraft/mod/tasks/LocalTexturePackParseTask.h"
+#include "minecraft/mod/tasks/LocalWorldSaveParseTask.h"
const static QMap forgemap = { { "1.2.5", "3.4.9.171" },
{ "1.4.2", "6.0.1.355" },
@@ -411,8 +412,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
QList blocked_mods;
auto anyBlocked = false;
for (const auto& result : results.files.values()) {
-
- if(result.fileName.endsWith(".zip")) {
+ if (result.fileName.endsWith(".zip")) {
m_ZIP_resources.append(std::make_pair(result.fileName, result.targetFolder));
}
@@ -454,7 +454,6 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
}
}
-
void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
{
m_files_job = new NetJob(tr("Mod download"), APPLICATION->network());
@@ -493,8 +492,8 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
}
m_mod_id_resolver.reset();
- connect(m_files_job.get(), &NetJob::succeeded, this, [&]() {
- m_files_job.reset();
+ connect(m_files_job.get(), &NetJob::succeeded, this, [&]() {
+ m_files_job.reset();
validateZIPResouces();
});
connect(m_files_job.get(), &NetJob::failed, [&](QString reason) {
@@ -543,26 +542,26 @@ void FlameCreationTask::copyBlockedMods(QList const& blocked_mods)
bool moveFile(QString src, QString dst)
{
if (!FS::copy(src, dst)()) { // copy
- qDebug() << "Copy of" << src << "to" << dst << "Failed!";
+ qDebug() << "Copy of" << src << "to" << dst << "failed!";
return false;
} else {
if (!FS::deletePath(src)) { // remove original
- qDebug() << "Deleation of" << src << "Failed!";
+ qDebug() << "Deletion of" << src << "failed!";
return false;
};
}
return true;
}
-
void FlameCreationTask::validateZIPResouces()
{
- qDebug() << "Validating resoucres stored as .zip are in the right place";
+ qDebug() << "Validating whether resources stored as .zip are in the right place";
for (auto [fileName, targetFolder] : m_ZIP_resources) {
-
qDebug() << "Checking" << fileName << "...";
auto localPath = FS::PathCombine(m_stagingPath, "minecraft", targetFolder, fileName);
+ /// @brief check the target and move the the file
+ /// @return path where file can now be found
auto validatePath = [&localPath, this](QString fileName, QString targetFolder, QString realTarget) {
if (targetFolder != realTarget) {
qDebug() << "Target folder of" << fileName << "is incorrect, it belongs in" << realTarget;
@@ -589,7 +588,7 @@ void FlameCreationTask::validateZIPResouces()
} else if (ModUtils::validate(localFileInfo)) {
qDebug() << fileName << "is a mod";
validatePath(fileName, targetFolder, "mods");
- } else if (WorldSaveUtils::validate(localFileInfo)) {
+ } else if (WorldSaveUtils::validate(localFileInfo)) {
qDebug() << fileName << "is a world save";
QString worldPath = validatePath(fileName, targetFolder, "saves");
@@ -600,7 +599,7 @@ void FlameCreationTask::validateZIPResouces()
qDebug() << "World at" << worldPath << "is not valid, skipping install.";
} else {
w.install(FS::PathCombine(m_stagingPath, "minecraft", "saves"));
- }
+ }
} else if (ShaderPackUtils::validate(localFileInfo)) {
// in theroy flame API can't do this but who knows, that *may* change ?
// better to handle it if it *does* occure in the future
@@ -610,7 +609,7 @@ void FlameCreationTask::validateZIPResouces()
qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is.";
}
} else {
- qDebug() << "Can't find" << localPath << "to validate it, ignoreing";
+ qDebug() << "Can't find" << localPath << "to validate it, ignoring";
}
}
}
diff --git a/tests/ResourcePackParse_test.cpp b/tests/ResourcePackParse_test.cpp
index 4192da31..7f2f86bf 100644
--- a/tests/ResourcePackParse_test.cpp
+++ b/tests/ResourcePackParse_test.cpp
@@ -67,7 +67,7 @@ class ResourcePackParseTest : public QObject {
QVERIFY(pack.packFormat() == 6);
QVERIFY(pack.description() == "o quartel pegou fogo, policia deu sinal, acode acode acode a bandeira nacional");
- QVERIFY(valid == false);
+ QVERIFY(valid == false); // no assets dir
}
};
--
cgit
From c470f05abf090232b27faac6014f9e1cbe9dab9b Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Thu, 29 Dec 2022 17:21:54 -0700
Subject: refactor: use std::filesystem::rename insted of copy and then moving.
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/FileSystem.cpp | 16 ++++++++++++++++
launcher/FileSystem.h | 8 ++++++++
launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 15 +--------------
3 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index 3e8e10a5..4390eed9 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -213,6 +213,22 @@ bool copy::operator()(const QString& offset, bool dryRun)
return err.value() == 0;
}
+bool move(const QString& source, const QString& dest)
+{
+ std::error_code err;
+
+ ensureFilePathExists(dest);
+ fs::rename(StringUtils::toStdString(source), StringUtils::toStdString(dest), err);
+
+ if (err) {
+ qWarning() << "Failed to move file:" << QString::fromStdString(err.message());
+ qDebug() << "Source file:" << source;
+ qDebug() << "Destination file:" << dest;
+ }
+
+ return err.value() == 0;
+}
+
bool deletePath(QString path)
{
std::error_code err;
diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h
index ac893725..1e3a60d9 100644
--- a/launcher/FileSystem.h
+++ b/launcher/FileSystem.h
@@ -121,6 +121,14 @@ class copy : public QObject {
int m_copied;
};
+/**
+ * @brief moves a file by renaming it
+ * @param source source file path
+ * @param dest destination filepath
+ *
+ */
+bool move(const QString& source, const QString& dest);
+
/**
* Delete a folder recursively
*/
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 79104e17..0a91879d 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -539,19 +539,6 @@ void FlameCreationTask::copyBlockedMods(QList const& blocked_mods)
setAbortable(true);
}
-bool moveFile(QString src, QString dst)
-{
- if (!FS::copy(src, dst)()) { // copy
- qDebug() << "Copy of" << src << "to" << dst << "failed!";
- return false;
- } else {
- if (!FS::deletePath(src)) { // remove original
- qDebug() << "Deletion of" << src << "failed!";
- return false;
- };
- }
- return true;
-}
void FlameCreationTask::validateZIPResouces()
{
@@ -567,7 +554,7 @@ void FlameCreationTask::validateZIPResouces()
qDebug() << "Target folder of" << fileName << "is incorrect, it belongs in" << realTarget;
auto destPath = FS::PathCombine(m_stagingPath, "minecraft", realTarget, fileName);
qDebug() << "Moving" << localPath << "to" << destPath;
- if (moveFile(localPath, destPath)) {
+ if (FS::move(localPath, destPath)) {
return destPath;
}
}
--
cgit
From 7f438425aa84db51211123b47622a828be0aeb96 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Thu, 29 Dec 2022 19:47:19 -0700
Subject: refactor: add an `identify` function to make easy to reuse
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/CMakeLists.txt | 2 +
.../minecraft/mod/tasks/LocalResourceParse.cpp | 60 +++++++++++++++++++
launcher/minecraft/mod/tasks/LocalResourceParse.h | 31 ++++++++++
.../flame/FlameInstanceCreationTask.cpp | 68 +++++++++++-----------
4 files changed, 128 insertions(+), 33 deletions(-)
create mode 100644 launcher/minecraft/mod/tasks/LocalResourceParse.cpp
create mode 100644 launcher/minecraft/mod/tasks/LocalResourceParse.h
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 853e1c03..9826d543 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -363,6 +363,8 @@ set(MINECRAFT_SOURCES
minecraft/mod/tasks/LocalShaderPackParseTask.cpp
minecraft/mod/tasks/LocalWorldSaveParseTask.h
minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
+ minecraft/mod/tasks/LocalResourceParse.h
+ minecraft/mod/tasks/LocalResourceParse.cpp
# Assets
minecraft/AssetsUtils.h
diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp
new file mode 100644
index 00000000..244b2f54
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp
@@ -0,0 +1,60 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#include "LocalResourceParse.h"
+
+#include "LocalDataPackParseTask.h"
+#include "LocalModParseTask.h"
+#include "LocalResourcePackParseTask.h"
+#include "LocalShaderPackParseTask.h"
+#include "LocalTexturePackParseTask.h"
+#include "LocalWorldSaveParseTask.h"
+
+namespace ResourceUtils {
+PackedResourceType identify(QFileInfo file){
+ if (file.exists() && file.isFile()) {
+ if (ResourcePackUtils::validate(file)) {
+ qDebug() << file.fileName() << "is a resource pack";
+ return PackedResourceType::ResourcePack;
+ } else if (TexturePackUtils::validate(file)) {
+ qDebug() << file.fileName() << "is a pre 1.6 texture pack";
+ return PackedResourceType::TexturePack;
+ } else if (DataPackUtils::validate(file)) {
+ qDebug() << file.fileName() << "is a data pack";
+ return PackedResourceType::DataPack;
+ } else if (ModUtils::validate(file)) {
+ qDebug() << file.fileName() << "is a mod";
+ return PackedResourceType::Mod;
+ } else if (WorldSaveUtils::validate(file)) {
+ qDebug() << file.fileName() << "is a world save";
+ return PackedResourceType::WorldSave;
+ } else if (ShaderPackUtils::validate(file)) {
+ qDebug() << file.fileName() << "is a shader pack";
+ return PackedResourceType::ShaderPack;
+ } else {
+ qDebug() << "Can't Identify" << file.fileName() ;
+ }
+ } else {
+ qDebug() << "Can't find" << file.absolutePath();
+ }
+ return PackedResourceType::UNKNOWN;
+}
+}
\ No newline at end of file
diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.h b/launcher/minecraft/mod/tasks/LocalResourceParse.h
new file mode 100644
index 00000000..b3e2829d
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/LocalResourceParse.h
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 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 .
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+enum class PackedResourceType { DataPack, ResourcePack, TexturePack, ShaderPack, WorldSave, Mod, UNKNOWN };
+namespace ResourceUtils {
+PackedResourceType identify(QFileInfo file);
+} // namespace ResourceUtils
\ No newline at end of file
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 0a91879d..dc69769a 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -57,12 +57,8 @@
#include
#include "minecraft/World.h"
-#include "minecraft/mod/tasks/LocalDataPackParseTask.h"
-#include "minecraft/mod/tasks/LocalModParseTask.h"
-#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
-#include "minecraft/mod/tasks/LocalShaderPackParseTask.h"
-#include "minecraft/mod/tasks/LocalTexturePackParseTask.h"
-#include "minecraft/mod/tasks/LocalWorldSaveParseTask.h"
+#include "minecraft/mod/tasks/LocalResourceParse.h"
+
const static QMap forgemap = { { "1.2.5", "3.4.9.171" },
{ "1.4.2", "6.0.1.355" },
@@ -561,42 +557,48 @@ void FlameCreationTask::validateZIPResouces()
return localPath;
};
+ auto installWorld = [this](QString worldPath){
+ qDebug() << "Installing World from" << worldPath;
+ QFileInfo worldFileInfo(worldPath);
+ World w(worldFileInfo);
+ if (!w.isValid()) {
+ qDebug() << "World at" << worldPath << "is not valid, skipping install.";
+ } else {
+ w.install(FS::PathCombine(m_stagingPath, "minecraft", "saves"));
+ }
+ };
+
QFileInfo localFileInfo(localPath);
- if (localFileInfo.exists() && localFileInfo.isFile()) {
- if (ResourcePackUtils::validate(localFileInfo)) {
- qDebug() << fileName << "is a resource pack";
+ auto type = ResourceUtils::identify(localFileInfo);
+
+ QString worldPath;
+
+ switch (type) {
+ case PackedResourceType::ResourcePack :
validatePath(fileName, targetFolder, "resourcepacks");
- } else if (TexturePackUtils::validate(localFileInfo)) {
- qDebug() << fileName << "is a pre 1.6 texture pack";
+ break;
+ case PackedResourceType::TexturePack :
validatePath(fileName, targetFolder, "texturepacks");
- } else if (DataPackUtils::validate(localFileInfo)) {
- qDebug() << fileName << "is a data pack";
+ break;
+ case PackedResourceType::DataPack :
validatePath(fileName, targetFolder, "datapacks");
- } else if (ModUtils::validate(localFileInfo)) {
- qDebug() << fileName << "is a mod";
+ break;
+ case PackedResourceType::Mod :
validatePath(fileName, targetFolder, "mods");
- } else if (WorldSaveUtils::validate(localFileInfo)) {
- qDebug() << fileName << "is a world save";
- QString worldPath = validatePath(fileName, targetFolder, "saves");
-
- qDebug() << "Installing World from" << worldPath;
- QFileInfo worldFileInfo(worldPath);
- World w(worldFileInfo);
- if (!w.isValid()) {
- qDebug() << "World at" << worldPath << "is not valid, skipping install.";
- } else {
- w.install(FS::PathCombine(m_stagingPath, "minecraft", "saves"));
- }
- } else if (ShaderPackUtils::validate(localFileInfo)) {
+ break;
+ case PackedResourceType::ShaderPack :
// in theroy flame API can't do this but who knows, that *may* change ?
// better to handle it if it *does* occure in the future
- qDebug() << fileName << "is a shader pack";
validatePath(fileName, targetFolder, "shaderpacks");
- } else {
+ break;
+ case PackedResourceType::WorldSave :
+ worldPath = validatePath(fileName, targetFolder, "saves");
+ installWorld(worldPath);
+ break;
+ case PackedResourceType::UNKNOWN :
+ default :
qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is.";
- }
- } else {
- qDebug() << "Can't find" << localPath << "to validate it, ignoring";
+ break;
}
}
}
--
cgit
From 0ebf04a021c633cd6a3cdd76514aa728dc253714 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 30 Dec 2022 10:21:49 -0700
Subject: fix newlines
Co-authored-by: flow
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/minecraft/mod/tasks/LocalResourceParse.cpp | 2 +-
launcher/minecraft/mod/tasks/LocalResourceParse.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp
index 244b2f54..19ddc899 100644
--- a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp
+++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp
@@ -57,4 +57,4 @@ PackedResourceType identify(QFileInfo file){
}
return PackedResourceType::UNKNOWN;
}
-}
\ No newline at end of file
+}
diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.h b/launcher/minecraft/mod/tasks/LocalResourceParse.h
index b3e2829d..b07a874c 100644
--- a/launcher/minecraft/mod/tasks/LocalResourceParse.h
+++ b/launcher/minecraft/mod/tasks/LocalResourceParse.h
@@ -28,4 +28,4 @@
enum class PackedResourceType { DataPack, ResourcePack, TexturePack, ShaderPack, WorldSave, Mod, UNKNOWN };
namespace ResourceUtils {
PackedResourceType identify(QFileInfo file);
-} // namespace ResourceUtils
\ No newline at end of file
+} // namespace ResourceUtils
--
cgit
From 2faf8332ee8523a5c097c744dc8e12e86d304230 Mon Sep 17 00:00:00 2001
From: byquanton <32410361+byquanton@users.noreply.github.com>
Date: Thu, 5 Jan 2023 17:08:41 +0100
Subject: fix: Add 1.16+ Forge library prefix in TechnicPackProcessor.cpp
Signed-off-by: byquanton <32410361+byquanton@users.noreply.github.com>
---
launcher/modplatform/technic/TechnicPackProcessor.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/modplatform/technic/TechnicPackProcessor.cpp b/launcher/modplatform/technic/TechnicPackProcessor.cpp
index 95feb4b2..df713a72 100644
--- a/launcher/modplatform/technic/TechnicPackProcessor.cpp
+++ b/launcher/modplatform/technic/TechnicPackProcessor.cpp
@@ -172,7 +172,7 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const
auto libraryObject = Json::ensureObject(library, {}, "");
auto libraryName = Json::ensureString(libraryObject, "name", "", "");
- if (libraryName.startsWith("net.minecraftforge:forge:") && libraryName.contains('-'))
+ if ((libraryName.startsWith("net.minecraftforge:forge:") || libraryName.startsWith("net.minecraftforge:fmlloader:")) && libraryName.contains('-'))
{
QString libraryVersion = libraryName.section(':', 2);
if (!libraryVersion.startsWith("1.7.10-"))
--
cgit
From f04703f09b35fa7449fe368b04565016e6482786 Mon Sep 17 00:00:00 2001
From: Joshua Goins
Date: Fri, 6 Jan 2023 15:05:19 -0500
Subject: Strip certain HTML tags when rendering mod pages
Some mod pages use certain tags for centering purposes, but trips up
hoedown.
Signed-off-by: Joshua Goins
---
launcher/ui/pages/modplatform/ModPage.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index 677bc4d6..75be25b2 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -428,6 +428,10 @@ void ModPage::updateUi()
text += "
";
HoeDown h;
+
+ // hoedown bug: it doesn't handle markdown surrounded by block tags (like center, div) so strip them
+ current.extraData.body.remove(QRegularExpression("<[^>]*(?:center|div)\\W*>"));
+
ui->packDescription->setHtml(text + (current.extraData.body.isEmpty() ? current.description : h.process(current.extraData.body.toUtf8())));
ui->packDescription->flush();
}
--
cgit
From 8140f5136d7389ea1c134f7eb84caaefe037a3d9 Mon Sep 17 00:00:00 2001
From: seth
Date: Fri, 6 Jan 2023 22:28:15 -0500
Subject: feat: add teawie
drawn by sympathytea (https://github.com/SympathyTea)
Signed-off-by: seth
---
launcher/resources/backgrounds/backgrounds.qrc | 1 +
launcher/resources/backgrounds/teawie.png | Bin 0 -> 187972 bytes
launcher/ui/pages/global/LauncherPage.cpp | 5 +++++
launcher/ui/pages/global/LauncherPage.ui | 5 +++++
4 files changed, 11 insertions(+)
create mode 100644 launcher/resources/backgrounds/teawie.png
diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index e55faf15..7ed9410b 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -13,5 +13,6 @@
rory-flat-xmas.png
rory-flat-bday.png
rory-flat-spooky.png
+ teawie.png
diff --git a/launcher/resources/backgrounds/teawie.png b/launcher/resources/backgrounds/teawie.png
new file mode 100644
index 00000000..dc32c51f
Binary files /dev/null and b/launcher/resources/backgrounds/teawie.png differ
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index cae0635f..bd7cec6a 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -351,6 +351,9 @@ void LauncherPage::applySettings()
case 2: // rory the cat flat edition
s->set("BackgroundCat", "rory-flat");
break;
+ case 3: // teawie
+ s->set("BackgroundCat", "teawie");
+ break;
}
s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked());
@@ -424,6 +427,8 @@ void LauncherPage::loadSettings()
ui->themeBackgroundCat->setCurrentIndex(1);
} else if (cat == "rory-flat") {
ui->themeBackgroundCat->setCurrentIndex(2);
+ } else if (cat == "teawie") {
+ ui->themeBackgroundCat->setCurrentIndex(3);
}
{
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index c44718a1..ded333aa 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -386,6 +386,11 @@
Rory ID 11 (flat edition, drawn by Ashtaka)
+ -
+
+ Teawie (drawn by SympathyTea)
+
+
--
cgit
From a5051327dbbb0b225e6badd05921d445d3022c7c Mon Sep 17 00:00:00 2001
From: seth
Date: Sat, 7 Jan 2023 03:42:15 -0500
Subject: feat: add spooky teawie
Signed-off-by: seth
---
launcher/resources/backgrounds/backgrounds.qrc | 1 +
launcher/resources/backgrounds/teawie-spooky.png | Bin 0 -> 183698 bytes
2 files changed, 1 insertion(+)
create mode 100644 launcher/resources/backgrounds/teawie-spooky.png
diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index 7ed9410b..87e70935 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -14,5 +14,6 @@
rory-flat-bday.png
rory-flat-spooky.png
teawie.png
+ teawie-spooky.png
diff --git a/launcher/resources/backgrounds/teawie-spooky.png b/launcher/resources/backgrounds/teawie-spooky.png
new file mode 100644
index 00000000..9c57103e
Binary files /dev/null and b/launcher/resources/backgrounds/teawie-spooky.png differ
--
cgit
From 2dbd775cf3eac7ca0b5d522af97623f5de129af3 Mon Sep 17 00:00:00 2001
From: seth
Date: Sat, 7 Jan 2023 04:13:53 -0500
Subject: feat: add xmas teawie
Signed-off-by: seth
---
launcher/resources/backgrounds/backgrounds.qrc | 1 +
launcher/resources/backgrounds/teawie-xmas.png | Bin 0 -> 200137 bytes
2 files changed, 1 insertion(+)
create mode 100644 launcher/resources/backgrounds/teawie-xmas.png
diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index 87e70935..dc16e788 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -14,6 +14,7 @@
rory-flat-bday.png
rory-flat-spooky.png
teawie.png
+ teawie-xmas.png
teawie-spooky.png
diff --git a/launcher/resources/backgrounds/teawie-xmas.png b/launcher/resources/backgrounds/teawie-xmas.png
new file mode 100644
index 00000000..55fb7cfc
Binary files /dev/null and b/launcher/resources/backgrounds/teawie-xmas.png differ
--
cgit
From e018b308751d1ead1819e8ffe69625fe26d90ff5 Mon Sep 17 00:00:00 2001
From: seth
Date: Sat, 7 Jan 2023 04:38:26 -0500
Subject: fix: make spooky teawie load
gimp fail
Signed-off-by: seth
---
launcher/resources/backgrounds/teawie-spooky.png | Bin 183698 -> 204756 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/launcher/resources/backgrounds/teawie-spooky.png b/launcher/resources/backgrounds/teawie-spooky.png
index 9c57103e..cefc6c85 100644
Binary files a/launcher/resources/backgrounds/teawie-spooky.png and b/launcher/resources/backgrounds/teawie-spooky.png differ
--
cgit
From f5955a4738ee5164c5c391086f1c4c0dde6d91a8 Mon Sep 17 00:00:00 2001
From: seth
Date: Sat, 7 Jan 2023 04:41:09 -0500
Subject: feat: add bday teawie
Signed-off-by: seth
---
launcher/resources/backgrounds/backgrounds.qrc | 1 +
launcher/resources/backgrounds/teawie-bday.png | Bin 0 -> 190586 bytes
2 files changed, 1 insertion(+)
create mode 100644 launcher/resources/backgrounds/teawie-bday.png
diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index dc16e788..83096aef 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -15,6 +15,7 @@
rory-flat-spooky.png
teawie.png
teawie-xmas.png
+ teawie-bday.png
teawie-spooky.png
diff --git a/launcher/resources/backgrounds/teawie-bday.png b/launcher/resources/backgrounds/teawie-bday.png
new file mode 100644
index 00000000..f4ecf247
Binary files /dev/null and b/launcher/resources/backgrounds/teawie-bday.png differ
--
cgit
From 9de6927c3fcdf813957dd6885b793a2c54100513 Mon Sep 17 00:00:00 2001
From: seth
Date: Sat, 7 Jan 2023 19:18:22 -0500
Subject: feat: add CC BY-SA 4.0 info for teawie images
Signed-off-by: seth
---
launcher/resources/backgrounds/backgrounds.qrc | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index 83096aef..e63a25b5 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -13,9 +13,17 @@
rory-flat-xmas.png
rory-flat-bday.png
rory-flat-spooky.png
+
+
+
+
teawie.png
+
teawie-xmas.png
+
teawie-bday.png
+
teawie-spooky.png
+
--
cgit
From 0481ae187acf3392aa158af9e6e287f8695d54ad Mon Sep 17 00:00:00 2001
From: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Date: Sun, 8 Jan 2023 10:34:45 +0100
Subject: chore: update windows msvc to qt 6.4.2
Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
---
.github/workflows/build.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b6e179e1..51b5a81d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -61,7 +61,7 @@ jobs:
qt_ver: 6
qt_host: windows
qt_arch: ''
- qt_version: '6.4.0'
+ qt_version: '6.4.2'
qt_modules: 'qt5compat qtimageformats'
qt_tools: ''
@@ -73,7 +73,7 @@ jobs:
qt_ver: 6
qt_host: windows
qt_arch: 'win64_msvc2019_arm64'
- qt_version: '6.4.0'
+ qt_version: '6.4.2'
qt_modules: 'qt5compat qtimageformats'
qt_tools: ''
--
cgit
From fca40c1c6b336cd4231852737fa817e1dd958c01 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sun, 8 Jan 2023 22:40:41 +0000
Subject: chore(deps): update hendrikmuhs/ccache-action action to v1.2.6
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 51b5a81d..406d079c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -143,7 +143,7 @@ jobs:
- name: Setup ccache
if: (runner.os != 'Windows' || matrix.msystem == '') && inputs.build_type == 'Debug'
- uses: hendrikmuhs/ccache-action@v1.2.5
+ uses: hendrikmuhs/ccache-action@v1.2.6
with:
key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}-${{ matrix.architecture }}
--
cgit
From 7fdc81236e36a092dc1cdb9e7237e50d705228c6 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 9 Jan 2023 07:54:22 +0000
Subject: chore(deps): update actions/cache action to v3.2.3
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 51b5a81d..3c2ede8e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -165,7 +165,7 @@ jobs:
- name: Retrieve ccache cache (Windows MinGW-w64)
if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug'
- uses: actions/cache@v3.2.2
+ uses: actions/cache@v3.2.3
with:
path: '${{ github.workspace }}\.ccache'
key: ${{ matrix.os }}-mingw-w64
--
cgit
From 78bbcac0eaf1bb9df1ac87dafffbef659116fd80 Mon Sep 17 00:00:00 2001
From: TheLastRar
Date: Mon, 9 Jan 2023 19:36:31 +0000
Subject: ui: Let Qt 6.4.2 handle dark mode titlebar
Signed-off-by: TheLastRar
---
launcher/Application.cpp | 16 +---------
launcher/CMakeLists.txt | 10 -------
launcher/ui/WinDarkmode.cpp | 32 --------------------
launcher/ui/WinDarkmode.h | 60 -------------------------------------
launcher/ui/themes/ThemeManager.cpp | 17 -----------
5 files changed, 1 insertion(+), 134 deletions(-)
delete mode 100644 launcher/ui/WinDarkmode.cpp
delete mode 100644 launcher/ui/WinDarkmode.h
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index ff34a168..9d528d7a 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -62,11 +62,6 @@
#include "ui/pages/global/APIPage.h"
#include "ui/pages/global/CustomCommandsPage.h"
-#ifdef Q_OS_WIN
-#include "ui/WinDarkmode.h"
-#include
-#endif
-
#include "ui/setupwizard/SetupWizard.h"
#include "ui/setupwizard/LanguageWizardPage.h"
#include "ui/setupwizard/JavaWizardPage.h"
@@ -1353,16 +1348,7 @@ MainWindow* Application::showMainWindow(bool minimized)
m_mainWindow = new MainWindow();
m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray()));
m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray()));
-#ifdef Q_OS_WIN
- if (IsWindows10OrGreater())
- {
- if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) {
- WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
- } else {
- WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false);
- }
- }
-#endif
+
if(minimized)
{
m_mainWindow->showMinimized();
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 8b5c63ff..57480671 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -937,16 +937,6 @@ SET(LAUNCHER_SOURCES
ui/instanceview/VisualGroup.h
)
-if(WIN32)
- set(LAUNCHER_SOURCES
- ${LAUNCHER_SOURCES}
-
- # GUI - dark titlebar for Windows 10/11
- ui/WinDarkmode.h
- ui/WinDarkmode.cpp
- )
-endif()
-
qt_wrap_ui(LAUNCHER_UI
ui/setupwizard/PasteWizardPage.ui
ui/pages/global/AccountListPage.ui
diff --git a/launcher/ui/WinDarkmode.cpp b/launcher/ui/WinDarkmode.cpp
deleted file mode 100644
index eac68e4f..00000000
--- a/launcher/ui/WinDarkmode.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include
-
-#include "WinDarkmode.h"
-
-namespace WinDarkmode {
-
-/* See https://github.com/statiolake/neovim-qt/commit/da8eaba7f0e38b6b51f3bacd02a8cc2d1f7a34d8 */
-void setDarkWinTitlebar(WId winid, bool darkmode)
-{
- HWND hwnd = reinterpret_cast(winid);
- BOOL dark = (BOOL) darkmode;
-
- HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
- HMODULE hUser32 = GetModuleHandleW(L"user32.dll");
- fnAllowDarkModeForWindow AllowDarkModeForWindow
- = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133)));
- fnSetPreferredAppMode SetPreferredAppMode
- = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135)));
- fnSetWindowCompositionAttribute SetWindowCompositionAttribute
- = reinterpret_cast(GetProcAddress(hUser32, "SetWindowCompositionAttribute"));
-
- SetPreferredAppMode(AllowDark);
- AllowDarkModeForWindow(hwnd, dark);
- WINDOWCOMPOSITIONATTRIBDATA data = {
- WCA_USEDARKMODECOLORS,
- &dark,
- sizeof(dark)
- };
- SetWindowCompositionAttribute(hwnd, &data);
-}
-
-}
diff --git a/launcher/ui/WinDarkmode.h b/launcher/ui/WinDarkmode.h
deleted file mode 100644
index 5b567c6b..00000000
--- a/launcher/ui/WinDarkmode.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include
-#include
-
-
-namespace WinDarkmode {
-
-void setDarkWinTitlebar(WId winid, bool darkmode);
-
-enum PreferredAppMode {
- Default,
- AllowDark,
- ForceDark,
- ForceLight,
- Max
-};
-
-enum WINDOWCOMPOSITIONATTRIB {
- WCA_UNDEFINED = 0,
- WCA_NCRENDERING_ENABLED = 1,
- WCA_NCRENDERING_POLICY = 2,
- WCA_TRANSITIONS_FORCEDISABLED = 3,
- WCA_ALLOW_NCPAINT = 4,
- WCA_CAPTION_BUTTON_BOUNDS = 5,
- WCA_NONCLIENT_RTL_LAYOUT = 6,
- WCA_FORCE_ICONIC_REPRESENTATION = 7,
- WCA_EXTENDED_FRAME_BOUNDS = 8,
- WCA_HAS_ICONIC_BITMAP = 9,
- WCA_THEME_ATTRIBUTES = 10,
- WCA_NCRENDERING_EXILED = 11,
- WCA_NCADORNMENTINFO = 12,
- WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
- WCA_VIDEO_OVERLAY_ACTIVE = 14,
- WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
- WCA_DISALLOW_PEEK = 16,
- WCA_CLOAK = 17,
- WCA_CLOAKED = 18,
- WCA_ACCENT_POLICY = 19,
- WCA_FREEZE_REPRESENTATION = 20,
- WCA_EVER_UNCLOAKED = 21,
- WCA_VISUAL_OWNER = 22,
- WCA_HOLOGRAPHIC = 23,
- WCA_EXCLUDED_FROM_DDA = 24,
- WCA_PASSIVEUPDATEMODE = 25,
- WCA_USEDARKMODECOLORS = 26,
- WCA_LAST = 27
-};
-
-struct WINDOWCOMPOSITIONATTRIBDATA {
- WINDOWCOMPOSITIONATTRIB Attrib;
- PVOID pvData;
- SIZE_T cbData;
-};
-
-using fnAllowDarkModeForWindow = BOOL (WINAPI *)(HWND hWnd, BOOL allow);
-using fnSetPreferredAppMode = PreferredAppMode (WINAPI *)(PreferredAppMode appMode);
-using fnSetWindowCompositionAttribute = BOOL (WINAPI *)(HWND hwnd, WINDOWCOMPOSITIONATTRIBDATA *);
-
-}
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 01a38a86..5a612472 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -28,14 +28,6 @@
#include "Application.h"
-#ifdef Q_OS_WIN
-#include
-// this is needed for versionhelpers.h, it is also included in WinDarkmode, but we can't rely on that.
-// Ultimately this should be included in versionhelpers, but that is outside of the project.
-#include "ui/WinDarkmode.h"
-#include
-#endif
-
ThemeManager::ThemeManager(MainWindow* mainWindow)
{
m_mainWindow = mainWindow;
@@ -140,15 +132,6 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial)
auto& theme = themeIter->second;
themeDebugLog() << "applying theme" << theme->name();
theme->apply(initial);
-#ifdef Q_OS_WIN
- if (m_mainWindow && IsWindows10OrGreater()) {
- if (QString::compare(theme->id(), "dark") == 0) {
- WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
- } else {
- WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false);
- }
- }
-#endif
} else {
themeWarningLog() << "Tried to set invalid theme:" << name;
}
--
cgit
From a113ecca8b86a0aa9a448795b49c9bb841ddc59a Mon Sep 17 00:00:00 2001
From: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
Date: Tue, 10 Jan 2023 15:00:39 +0100
Subject: fix: just use github runner's openssl 1.1 instead of installing 3 on
macos signing
Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com>
---
.github/workflows/build.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9d75a457..e0a80f20 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -342,9 +342,8 @@ jobs:
if: matrix.name == 'macOS'
run: |
if [ '${{ secrets.SPARKLE_ED25519_KEY }}' != '' ]; then
- brew install openssl@3
echo '${{ secrets.SPARKLE_ED25519_KEY }}' > ed25519-priv.pem
- signature=$(/usr/local/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/PrismLauncher.tar.gz -inkey ed25519-priv.pem | openssl base64 | tr -d \\n)
+ signature=$(openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/PrismLauncher.tar.gz -inkey ed25519-priv.pem | openssl base64 | tr -d \\n)
rm ed25519-priv.pem
cat >> $GITHUB_STEP_SUMMARY << EOF
### Artifact Information :information_source:
--
cgit
From 1b80ae0fca5e41d8caaa7d77d19faa9826752143 Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sat, 22 Oct 2022 19:43:04 +0200
Subject: add theme setup wizard
Signed-off-by: Tayou
---
launcher/Application.cpp | 21 +-
launcher/Application.h | 4 +-
launcher/CMakeLists.txt | 6 +
launcher/ui/MainWindow.cpp | 2 +-
launcher/ui/pages/global/LauncherPage.cpp | 110 --------
launcher/ui/pages/global/LauncherPage.ui | 166 +----------
launcher/ui/setupwizard/ThemeWizardPage.cpp | 70 +++++
launcher/ui/setupwizard/ThemeWizardPage.h | 44 +++
launcher/ui/setupwizard/ThemeWizardPage.ui | 336 +++++++++++++++++++++++
launcher/ui/themes/ITheme.cpp | 40 ++-
launcher/ui/themes/ITheme.h | 36 ++-
launcher/ui/themes/SystemTheme.cpp | 9 +-
launcher/ui/themes/SystemTheme.h | 36 ++-
launcher/ui/themes/ThemeManager.cpp | 6 +-
launcher/ui/themes/ThemeManager.h | 3 +-
launcher/ui/widgets/ThemeCustomizationWidget.cpp | 135 +++++++++
launcher/ui/widgets/ThemeCustomizationWidget.h | 64 +++++
launcher/ui/widgets/ThemeCustomizationWidget.ui | 182 ++++++++++++
18 files changed, 982 insertions(+), 288 deletions(-)
create mode 100644 launcher/ui/setupwizard/ThemeWizardPage.cpp
create mode 100644 launcher/ui/setupwizard/ThemeWizardPage.h
create mode 100644 launcher/ui/setupwizard/ThemeWizardPage.ui
create mode 100644 launcher/ui/widgets/ThemeCustomizationWidget.cpp
create mode 100644 launcher/ui/widgets/ThemeCustomizationWidget.h
create mode 100644 launcher/ui/widgets/ThemeCustomizationWidget.ui
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 9d528d7a..3e64b74f 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -66,6 +66,7 @@
#include "ui/setupwizard/LanguageWizardPage.h"
#include "ui/setupwizard/JavaWizardPage.h"
#include "ui/setupwizard/PasteWizardPage.h"
+#include "ui/setupwizard/ThemeWizardPage.h"
#include "ui/dialogs/CustomMessageBox.h"
@@ -846,10 +847,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
});
{
- setIconTheme(settings()->get("IconTheme").toString());
- qDebug() << "<> Icon theme set.";
- setApplicationTheme(settings()->get("ApplicationTheme").toString(), true);
- qDebug() << "<> Application theme set.";
+ applyCurrentlySelectedTheme();
}
updateCapabilities();
@@ -892,6 +890,7 @@ bool Application::createSetupWizard()
return false;
}();
bool pasteInterventionRequired = settings()->get("PastebinURL") != "";
+ bool themeInterventionRequired = settings()->get("ApplicationTheme") != "";
bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired;
if(wizardRequired)
@@ -911,6 +910,11 @@ bool Application::createSetupWizard()
{
m_setupWizard->addPage(new PasteWizardPage(m_setupWizard));
}
+
+ if (themeInterventionRequired)
+ {
+ m_setupWizard->addPage(new ThemeWizardPage(m_setupWizard));
+ }
connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished);
m_setupWizard->show();
return true;
@@ -1118,9 +1122,14 @@ QList Application::getValidApplicationThemes()
return m_themeManager->getValidApplicationThemes();
}
-void Application::setApplicationTheme(const QString& name, bool initial)
+void Application::applyCurrentlySelectedTheme()
+{
+ m_themeManager->applyCurrentlySelectedTheme();
+}
+
+void Application::setApplicationTheme(const QString& name)
{
- m_themeManager->setApplicationTheme(name, initial);
+ m_themeManager->setApplicationTheme(name);
}
void Application::setIconTheme(const QString& name)
diff --git a/launcher/Application.h b/launcher/Application.h
index 7884227a..a7938629 100644
--- a/launcher/Application.h
+++ b/launcher/Application.h
@@ -120,9 +120,11 @@ public:
void setIconTheme(const QString& name);
+ void applyCurrentlySelectedTheme();
+
QList getValidApplicationThemes();
- void setApplicationTheme(const QString& name, bool initial);
+ void setApplicationTheme(const QString& name);
shared_qobject_ptr updateChecker() {
return m_updateChecker;
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 57480671..74b7b212 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -683,6 +683,8 @@ SET(LAUNCHER_SOURCES
ui/setupwizard/LanguageWizardPage.h
ui/setupwizard/PasteWizardPage.cpp
ui/setupwizard/PasteWizardPage.h
+ ui/setupwizard/ThemeWizardPage.cpp
+ ui/setupwizard/ThemeWizardPage.h
# GUI - themes
ui/themes/FusionTheme.cpp
@@ -922,6 +924,8 @@ SET(LAUNCHER_SOURCES
ui/widgets/ProgressWidget.cpp
ui/widgets/WideBar.h
ui/widgets/WideBar.cpp
+ ui/widgets/ThemeCustomizationWidget.h
+ ui/widgets/ThemeCustomizationWidget.cpp
# GUI - instance group view
ui/instanceview/InstanceProxyModel.cpp
@@ -939,6 +943,7 @@ SET(LAUNCHER_SOURCES
qt_wrap_ui(LAUNCHER_UI
ui/setupwizard/PasteWizardPage.ui
+ ui/setupwizard/ThemeWizardPage.ui
ui/pages/global/AccountListPage.ui
ui/pages/global/JavaPage.ui
ui/pages/global/LauncherPage.ui
@@ -971,6 +976,7 @@ qt_wrap_ui(LAUNCHER_UI
ui/widgets/CustomCommands.ui
ui/widgets/InfoFrame.ui
ui/widgets/ModFilterWidget.ui
+ ui/widgets/ThemeCustomizationWidget.ui
ui/dialogs/CopyInstanceDialog.ui
ui/dialogs/ProfileSetupDialog.ui
ui/dialogs/ProgressDialog.ui
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index e913849d..331ca0e1 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -1346,7 +1346,7 @@ void MainWindow::updateThemeMenu()
themeAction->setActionGroup(themesGroup);
connect(themeAction, &QAction::triggered, [theme]() {
- APPLICATION->setApplicationTheme(theme->id(),false);
+ APPLICATION->setApplicationTheme(theme->id());
APPLICATION->settings()->set("ApplicationTheme", theme->id());
});
}
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index bd7cec6a..69a8e3df 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -286,75 +286,6 @@ void LauncherPage::applySettings()
}
s->set("UpdateChannel", m_currentUpdateChannel);
- auto original = s->get("IconTheme").toString();
- //FIXME: make generic
- switch (ui->themeComboBox->currentIndex())
- {
- case 0:
- s->set("IconTheme", "pe_colored");
- break;
- case 1:
- s->set("IconTheme", "pe_light");
- break;
- case 2:
- s->set("IconTheme", "pe_dark");
- break;
- case 3:
- s->set("IconTheme", "pe_blue");
- break;
- case 4:
- s->set("IconTheme", "breeze_light");
- break;
- case 5:
- s->set("IconTheme", "breeze_dark");
- break;
- case 6:
- s->set("IconTheme", "OSX");
- break;
- case 7:
- s->set("IconTheme", "iOS");
- break;
- case 8:
- s->set("IconTheme", "flat");
- break;
- case 9:
- s->set("IconTheme", "flat_white");
- break;
- case 10:
- s->set("IconTheme", "multimc");
- break;
- case 11:
- s->set("IconTheme", "custom");
- break;
- }
-
- if(original != s->get("IconTheme"))
- {
- APPLICATION->setIconTheme(s->get("IconTheme").toString());
- }
-
- auto originalAppTheme = s->get("ApplicationTheme").toString();
- auto newAppTheme = ui->themeComboBoxColors->currentData().toString();
- if(originalAppTheme != newAppTheme)
- {
- s->set("ApplicationTheme", newAppTheme);
- APPLICATION->setApplicationTheme(newAppTheme, false);
- }
-
- switch (ui->themeBackgroundCat->currentIndex()) {
- case 0: // original cat
- s->set("BackgroundCat", "kitteh");
- break;
- case 1: // rory the cat
- s->set("BackgroundCat", "rory");
- break;
- case 2: // rory the cat flat edition
- s->set("BackgroundCat", "rory-flat");
- break;
- case 3: // teawie
- s->set("BackgroundCat", "teawie");
- break;
- }
s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked());
@@ -404,47 +335,6 @@ void LauncherPage::loadSettings()
}
m_currentUpdateChannel = s->get("UpdateChannel").toString();
- //FIXME: make generic
- auto theme = s->get("IconTheme").toString();
- QStringList iconThemeOptions{"pe_colored",
- "pe_light",
- "pe_dark",
- "pe_blue",
- "breeze_light",
- "breeze_dark",
- "OSX",
- "iOS",
- "flat",
- "flat_white",
- "multimc",
- "custom"};
- ui->themeComboBox->setCurrentIndex(iconThemeOptions.indexOf(theme));
-
- auto cat = s->get("BackgroundCat").toString();
- if (cat == "kitteh") {
- ui->themeBackgroundCat->setCurrentIndex(0);
- } else if (cat == "rory") {
- ui->themeBackgroundCat->setCurrentIndex(1);
- } else if (cat == "rory-flat") {
- ui->themeBackgroundCat->setCurrentIndex(2);
- } else if (cat == "teawie") {
- ui->themeBackgroundCat->setCurrentIndex(3);
- }
-
- {
- auto currentTheme = s->get("ApplicationTheme").toString();
- auto themes = APPLICATION->getValidApplicationThemes();
- int idx = 0;
- for(auto &theme: themes)
- {
- ui->themeComboBoxColors->addItem(theme->name(), theme->id());
- if(currentTheme == theme->id())
- {
- ui->themeComboBoxColors->setCurrentIndex(idx);
- }
- idx++;
- }
- }
// Toolbar/menu bar settings (not applicable if native menu bar is present)
ui->toolsBox->setEnabled(!QMenuBar().isNativeMenuBar());
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index ded333aa..65f4a9d5 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -6,7 +6,7 @@
0
0
- 514
+ 511
629
@@ -38,7 +38,7 @@
QTabWidget::Rounded
- 0
+ 1
@@ -243,155 +243,9 @@
Theme
-
- -
-
-
- &Icons
-
-
- themeComboBox
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::StrongFocus
-
-
-
-
- Simple (Colored Icons)
-
-
- -
-
- Simple (Light Icons)
-
-
- -
-
- Simple (Dark Icons)
-
-
- -
-
- Simple (Blue Icons)
-
-
- -
-
- Breeze Light
-
-
- -
-
- Breeze Dark
-
-
- -
-
- OSX
-
-
- -
-
- iOS
-
-
- -
-
- Flat
-
-
- -
-
- Flat (White)
-
-
- -
-
- Legacy
-
-
- -
-
- Custom
-
-
-
-
- -
-
-
- &Colors
-
-
- themeComboBoxColors
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::StrongFocus
-
-
-
- -
-
-
- C&at
-
-
- themeBackgroundCat
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::StrongFocus
-
-
-
-
- Background Cat (from MultiMC)
-
-
- -
-
- Rory ID 11 (drawn by Ashtaka)
-
-
- -
-
- Rory ID 11 (flat edition, drawn by Ashtaka)
-
-
- -
-
- Teawie (drawn by SympathyTea)
-
-
-
+
+ -
+
@@ -575,6 +429,14 @@
+
+
+ ThemeCustomizationWidget
+ QWidget
+ ui/widgets/ThemeCustomizationWidget.h
+ 1
+
+
tabWidget
autoUpdateCheckBox
@@ -587,8 +449,6 @@
iconsDirBrowseBtn
sortLastLaunchedBtn
sortByNameBtn
- themeComboBox
- themeComboBoxColors
showConsoleCheck
autoCloseConsoleCheck
showConsoleErrorCheck
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp
new file mode 100644
index 00000000..6f041134
--- /dev/null
+++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#include "ThemeWizardPage.h"
+#include "ui_ThemeWizardPage.h"
+
+#include "Application.h"
+#include "ui/themes/ITheme.h"
+#include "ui/widgets/ThemeCustomizationWidget.h"
+#include "ui_ThemeCustomizationWidget.h"
+
+ThemeWizardPage::ThemeWizardPage(QWidget *parent) :
+BaseWizardPage(parent),
+ui(new Ui::ThemeWizardPage) {
+ ui->setupUi(this);
+
+ ui->themeCustomizationWidget->showFeatures((ThemeFields)(ThemeFields::ICONS | ThemeFields::WIDGETS));
+ connect(ui->themeCustomizationWidget, QOverload::of(&ThemeCustomizationWidget::currentIconThemeChanged), this, &ThemeWizardPage::updateIcons);
+
+ updateIcons();
+}
+
+ThemeWizardPage::~ThemeWizardPage() {
+delete ui;
+}
+
+void ThemeWizardPage::initializePage()
+{
+}
+
+bool ThemeWizardPage::validatePage()
+{
+ return true;
+}
+
+void ThemeWizardPage::updateIcons() {
+ qDebug() << "Setting Icons";
+ ui->previewIconButton0->setIcon(APPLICATION->getThemedIcon("new"));
+ ui->previewIconButton1->setIcon(APPLICATION->getThemedIcon("centralmods"));
+ ui->previewIconButton2->setIcon(APPLICATION->getThemedIcon("viewfolder"));
+ ui->previewIconButton3->setIcon(APPLICATION->getThemedIcon("launch"));
+ ui->previewIconButton4->setIcon(APPLICATION->getThemedIcon("copy"));
+ ui->previewIconButton5->setIcon(APPLICATION->getThemedIcon("export"));
+ ui->previewIconButton6->setIcon(APPLICATION->getThemedIcon("delete"));
+ ui->previewIconButton7->setIcon(APPLICATION->getThemedIcon("about"));
+ ui->previewIconButton8->setIcon(APPLICATION->getThemedIcon("settings"));
+ ui->previewIconButton9->setIcon(APPLICATION->getThemedIcon("cat"));
+ update();
+ repaint();
+ parentWidget()->update();
+}
+
+void ThemeWizardPage::retranslate()
+{
+ ui->retranslateUi(this);
+}
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h
new file mode 100644
index 00000000..10913d1b
--- /dev/null
+++ b/launcher/ui/setupwizard/ThemeWizardPage.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#pragma once
+
+#include
+#include "BaseWizardPage.h"
+
+namespace Ui {
+class ThemeWizardPage;
+}
+
+class ThemeWizardPage : public BaseWizardPage
+{
+ Q_OBJECT
+
+public:
+ explicit ThemeWizardPage(QWidget *parent = nullptr);
+ ~ThemeWizardPage();
+
+ void initializePage() override;
+ bool validatePage() override;
+ void retranslate() override;
+
+private slots:
+ void updateIcons();
+
+private:
+ Ui::ThemeWizardPage *ui;
+};
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.ui b/launcher/ui/setupwizard/ThemeWizardPage.ui
new file mode 100644
index 00000000..b743644f
--- /dev/null
+++ b/launcher/ui/setupwizard/ThemeWizardPage.ui
@@ -0,0 +1,336 @@
+
+
+ ThemeWizardPage
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ WizardPage
+
+
+ -
+
+
+ Select the Theme you wish to use
+
+
+
+ -
+
+
+
+ 0
+ 100
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Icon Preview:
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 193
+
+
+
+
+
+
+
+
+ ThemeCustomizationWidget
+ QWidget
+ ui/widgets/ThemeCustomizationWidget.h
+
+
+
+
+
diff --git a/launcher/ui/themes/ITheme.cpp b/launcher/ui/themes/ITheme.cpp
index 8bfc466d..22043e44 100644
--- a/launcher/ui/themes/ITheme.cpp
+++ b/launcher/ui/themes/ITheme.cpp
@@ -1,19 +1,51 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 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 "ITheme.h"
#include "rainbow.h"
#include
#include
#include "Application.h"
-void ITheme::apply(bool)
+void ITheme::apply()
{
APPLICATION->setStyleSheet(QString());
QApplication::setStyle(QStyleFactory::create(qtTheme()));
if (hasColorScheme()) {
QApplication::setPalette(colorScheme());
}
- if (hasStyleSheet())
- APPLICATION->setStyleSheet(appStyleSheet());
-
+ APPLICATION->setStyleSheet(appStyleSheet());
QDir::setSearchPaths("theme", searchPaths());
}
diff --git a/launcher/ui/themes/ITheme.h b/launcher/ui/themes/ITheme.h
index c2347cf6..bb5c8afe 100644
--- a/launcher/ui/themes/ITheme.h
+++ b/launcher/ui/themes/ITheme.h
@@ -1,3 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 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
#include
@@ -8,7 +42,7 @@ class ITheme
{
public:
virtual ~ITheme() {}
- virtual void apply(bool initial);
+ virtual void apply();
virtual QString id() = 0;
virtual QString name() = 0;
virtual bool hasStyleSheet() = 0;
diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp
index a63d1741..d6ef442b 100644
--- a/launcher/ui/themes/SystemTheme.cpp
+++ b/launcher/ui/themes/SystemTheme.cpp
@@ -62,14 +62,9 @@ SystemTheme::SystemTheme()
themeDebugLog() << "System theme not found, defaulted to Fusion";
}
-void SystemTheme::apply(bool initial)
+void SystemTheme::apply()
{
- // if we are applying the system theme as the first theme, just don't touch anything. it's for the better...
- if(initial)
- {
- return;
- }
- ITheme::apply(initial);
+ ITheme::apply();
}
QString SystemTheme::id()
diff --git a/launcher/ui/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h
index fe450600..5c9216eb 100644
--- a/launcher/ui/themes/SystemTheme.h
+++ b/launcher/ui/themes/SystemTheme.h
@@ -1,3 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2013-2021 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 "ITheme.h"
@@ -7,7 +41,7 @@ class SystemTheme: public ITheme
public:
SystemTheme();
virtual ~SystemTheme() {}
- void apply(bool initial) override;
+ void apply() override;
QString id() override;
QString name() override;
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 5a612472..a6cebc6f 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -120,18 +120,18 @@ void ThemeManager::applyCurrentlySelectedTheme()
{
setIconTheme(APPLICATION->settings()->get("IconTheme").toString());
themeDebugLog() << "<> Icon theme set.";
- setApplicationTheme(APPLICATION->settings()->get("ApplicationTheme").toString(), true);
+ setApplicationTheme(APPLICATION->settings()->get("ApplicationTheme").toString());
themeDebugLog() << "<> Application theme set.";
}
-void ThemeManager::setApplicationTheme(const QString& name, bool initial)
+void ThemeManager::setApplicationTheme(const QString& name)
{
auto systemPalette = qApp->palette();
auto themeIter = m_themes.find(name);
if (themeIter != m_themes.end()) {
auto& theme = themeIter->second;
themeDebugLog() << "applying theme" << theme->name();
- theme->apply(initial);
+ theme->apply();
} else {
themeWarningLog() << "Tried to set invalid theme:" << name;
}
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index b85cb742..0a70ddfc 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -41,11 +41,12 @@ class ThemeManager {
QList getValidApplicationThemes();
void setIconTheme(const QString& name);
void applyCurrentlySelectedTheme();
- void setApplicationTheme(const QString& name, bool initial);
+ void setApplicationTheme(const QString& name);
private:
std::map> m_themes;
MainWindow* m_mainWindow;
+ bool m_firstThemeInitialized;
QString AddTheme(std::unique_ptr theme);
ITheme* GetTheme(QString themeId);
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
new file mode 100644
index 00000000..0830a030
--- /dev/null
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#include "ThemeCustomizationWidget.h"
+#include "ui_ThemeCustomizationWidget.h"
+
+#include "Application.h"
+#include "ui/themes/ITheme.h"
+
+ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget)
+{
+ ui->setupUi(this);
+ loadSettings();
+
+ connect(ui->iconsComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyIconTheme);
+ connect(ui->widgetStyleComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyWidgetTheme);
+ connect(ui->backgroundCatComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &ThemeCustomizationWidget::applyCatTheme);
+}
+
+ThemeCustomizationWidget::~ThemeCustomizationWidget()
+{
+ delete ui;
+}
+
+void ThemeCustomizationWidget::showFeatures(ThemeFields features) {
+ ui->iconsComboBox->setVisible(features & ThemeFields::ICONS);
+ ui->iconsLabel->setVisible(features & ThemeFields::ICONS);
+ ui->widgetStyleComboBox->setVisible(features & ThemeFields::WIDGETS);
+ ui->widgetThemeLabel->setVisible(features & ThemeFields::WIDGETS);
+ ui->backgroundCatComboBox->setVisible(features & ThemeFields::CAT);
+ ui->backgroundCatLabel->setVisible(features & ThemeFields::CAT);
+}
+
+void ThemeCustomizationWidget::applyIconTheme(int index) {
+ emit currentIconThemeChanged(index);
+
+ auto settings = APPLICATION->settings();
+ auto original = settings->get("IconTheme").toString();
+ // FIXME: make generic
+ settings->set("IconTheme", m_iconThemeOptions[index]);
+
+ if (original != settings->get("IconTheme")) {
+ APPLICATION->applyCurrentlySelectedTheme();
+ }
+}
+
+void ThemeCustomizationWidget::applyWidgetTheme(int index) {
+ emit currentWidgetThemeChanged(index);
+
+ auto settings = APPLICATION->settings();
+ auto originalAppTheme = settings->get("ApplicationTheme").toString();
+ auto newAppTheme = ui->widgetStyleComboBox->currentData().toString();
+ if (originalAppTheme != newAppTheme) {
+ settings->set("ApplicationTheme", newAppTheme);
+ APPLICATION->applyCurrentlySelectedTheme();
+ }
+}
+
+void ThemeCustomizationWidget::applyCatTheme(int index) {
+ emit currentCatChanged(index);
+
+ auto settings = APPLICATION->settings();
+ switch (index) {
+ case 0: // original cat
+ settings->set("BackgroundCat", "kitteh");
+ break;
+ case 1: // rory the cat
+ settings->set("BackgroundCat", "rory");
+ break;
+ case 2: // rory the cat flat edition
+ settings->set("BackgroundCat", "rory-flat");
+ break;
+ case 3: // teawie
+ settings->set("BackgroundCat", "teawie");
+ break;
+ }
+}
+
+void ThemeCustomizationWidget::applySettings()
+{
+ applyIconTheme(ui->iconsComboBox->currentIndex());
+ applyWidgetTheme(ui->widgetStyleComboBox->currentIndex());
+ applyCatTheme(ui->backgroundCatComboBox->currentIndex());
+}
+void ThemeCustomizationWidget::loadSettings()
+{
+ auto settings = APPLICATION->settings();
+
+ // FIXME: make generic
+ auto theme = settings->get("IconTheme").toString();
+ ui->iconsComboBox->setCurrentIndex(m_iconThemeOptions.indexOf(theme));
+
+ {
+ auto currentTheme = settings->get("ApplicationTheme").toString();
+ auto themes = APPLICATION->getValidApplicationThemes();
+ int idx = 0;
+ for (auto& theme : themes) {
+ ui->widgetStyleComboBox->addItem(theme->name(), theme->id());
+ if (currentTheme == theme->id()) {
+ ui->widgetStyleComboBox->setCurrentIndex(idx);
+ }
+ idx++;
+ }
+ }
+
+ auto cat = settings->get("BackgroundCat").toString();
+ if (cat == "kitteh") {
+ ui->backgroundCatComboBox->setCurrentIndex(0);
+ } else if (cat == "rory") {
+ ui->backgroundCatComboBox->setCurrentIndex(1);
+ } else if (cat == "rory-flat") {
+ ui->backgroundCatComboBox->setCurrentIndex(2);
+ } else if (cat == "teawie") {
+ ui->backgroundCatComboBox->setCurrentIndex(3);
+ }
+}
+
+void ThemeCustomizationWidget::retranslate()
+{
+ ui->retranslateUi(this);
+}
\ No newline at end of file
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h
new file mode 100644
index 00000000..e17286e1
--- /dev/null
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.h
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#pragma once
+
+#include
+#include
+
+enum ThemeFields {
+ NONE = 0b0000,
+ ICONS = 0b0001,
+ WIDGETS = 0b0010,
+ CAT = 0b0100
+};
+
+namespace Ui {
+class ThemeCustomizationWidget;
+}
+
+class ThemeCustomizationWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ThemeCustomizationWidget(QWidget *parent = nullptr);
+ ~ThemeCustomizationWidget();
+
+ void showFeatures(ThemeFields features);
+
+ void applySettings();
+
+ void loadSettings();
+ void retranslate();
+
+ Ui::ThemeCustomizationWidget *ui;
+
+private slots:
+ void applyIconTheme(int index);
+ void applyWidgetTheme(int index);
+ void applyCatTheme(int index);
+
+signals:
+ int currentIconThemeChanged(int index);
+ int currentWidgetThemeChanged(int index);
+ int currentCatChanged(int index);
+
+private:
+
+ QStringList m_iconThemeOptions{ "pe_colored", "pe_light", "pe_dark", "pe_blue", "breeze_light", "breeze_dark", "OSX", "iOS", "flat", "flat_white", "multimc", "custom" };
+};
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui
new file mode 100644
index 00000000..c184b8f3
--- /dev/null
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.ui
@@ -0,0 +1,182 @@
+
+
+ ThemeCustomizationWidget
+
+
+
+ 0
+ 0
+ 400
+ 311
+
+
+
+ Form
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ &Icons
+
+
+ iconsComboBox
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::StrongFocus
+
+
-
+
+ Simple (Colored Icons)
+
+
+ -
+
+ Simple (Light Icons)
+
+
+ -
+
+ Simple (Dark Icons)
+
+
+ -
+
+ Simple (Blue Icons)
+
+
+ -
+
+ Breeze Light
+
+
+ -
+
+ Breeze Dark
+
+
+ -
+
+ OSX
+
+
+ -
+
+ iOS
+
+
+ -
+
+ Flat
+
+
+ -
+
+ Flat (White)
+
+
+ -
+
+ Legacy
+
+
+ -
+
+ Custom
+
+
+
+
+ -
+
+
+ &Colors
+
+
+ widgetStyleComboBox
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::StrongFocus
+
+
+
+ -
+
+
+ C&at
+
+
+ backgroundCatComboBox
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::StrongFocus
+
+
-
+
+ Background Cat (from MultiMC)
+
+
+ -
+
+ Rory ID 11 (drawn by Ashtaka)
+
+
+ -
+
+ Rory ID 11 (flat edition, drawn by Ashtaka)
+
+
+ -
+
+ Teawie (drawn by SympathyTea)
+
+
+
+
+
+
+
+
+
--
cgit
From 49d317b19aa61fed056e0f14c12eb1997f68982d Mon Sep 17 00:00:00 2001
From: Tayou
Date: Mon, 9 Jan 2023 16:54:10 +0100
Subject: UX tweak + formatting + added cat to wizard
Signed-off-by: Tayou
---
launcher/ui/MainWindow.cpp | 16 +----
launcher/ui/setupwizard/ThemeWizardPage.cpp | 39 +++++++++---
launcher/ui/setupwizard/ThemeWizardPage.h | 1 +
launcher/ui/setupwizard/ThemeWizardPage.ui | 26 +++++++-
launcher/ui/themes/CustomTheme.cpp | 31 +++-------
launcher/ui/themes/ITheme.h | 12 ++--
launcher/ui/themes/SystemTheme.cpp | 12 ++--
launcher/ui/themes/SystemTheme.h | 8 +--
launcher/ui/themes/ThemeManager.h | 4 +-
launcher/ui/widgets/ThemeCustomizationWidget.cpp | 79 ++++++++++++------------
launcher/ui/widgets/ThemeCustomizationWidget.h | 1 +
launcher/ui/widgets/ThemeCustomizationWidget.ui | 5 +-
12 files changed, 127 insertions(+), 107 deletions(-)
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 331ca0e1..a921e378 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -1652,16 +1652,6 @@ void MainWindow::onCatToggled(bool state)
APPLICATION->settings()->set("TheCat", state);
}
-namespace {
-template
-T non_stupid_abs(T in)
-{
- if (in < 0)
- return -in;
- return in;
-}
-}
-
void MainWindow::setCatBackground(bool enabled)
{
if (enabled)
@@ -1671,11 +1661,11 @@ void MainWindow::setCatBackground(bool enabled)
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
QString cat = APPLICATION->settings()->get("BackgroundCat").toString();
- if (non_stupid_abs(now.daysTo(xmas)) <= 4) {
+ if (std::abs(now.daysTo(xmas)) <= 4) {
cat += "-xmas";
- } else if (non_stupid_abs(now.daysTo(halloween)) <= 4) {
+ } else if (std::abs(now.daysTo(halloween)) <= 4) {
cat += "-spooky";
- } else if (non_stupid_abs(now.daysTo(birthday)) <= 12) {
+ } else if (std::abs(now.daysTo(birthday)) <= 12) {
cat += "-bday";
}
view->setStyleSheet(QString(R"(
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp
index 6f041134..4e1eb488 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.cpp
+++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp
@@ -23,31 +23,31 @@
#include "ui/widgets/ThemeCustomizationWidget.h"
#include "ui_ThemeCustomizationWidget.h"
-ThemeWizardPage::ThemeWizardPage(QWidget *parent) :
-BaseWizardPage(parent),
-ui(new Ui::ThemeWizardPage) {
+ThemeWizardPage::ThemeWizardPage(QWidget* parent) : BaseWizardPage(parent), ui(new Ui::ThemeWizardPage)
+{
ui->setupUi(this);
- ui->themeCustomizationWidget->showFeatures((ThemeFields)(ThemeFields::ICONS | ThemeFields::WIDGETS));
connect(ui->themeCustomizationWidget, QOverload::of(&ThemeCustomizationWidget::currentIconThemeChanged), this, &ThemeWizardPage::updateIcons);
+ connect(ui->themeCustomizationWidget, QOverload::of(&ThemeCustomizationWidget::currentCatChanged), this, &ThemeWizardPage::updateCat);
updateIcons();
+ updateCat();
}
-ThemeWizardPage::~ThemeWizardPage() {
-delete ui;
-}
-
-void ThemeWizardPage::initializePage()
+ThemeWizardPage::~ThemeWizardPage()
{
+ delete ui;
}
+void ThemeWizardPage::initializePage() {}
+
bool ThemeWizardPage::validatePage()
{
return true;
}
-void ThemeWizardPage::updateIcons() {
+void ThemeWizardPage::updateIcons()
+{
qDebug() << "Setting Icons";
ui->previewIconButton0->setIcon(APPLICATION->getThemedIcon("new"));
ui->previewIconButton1->setIcon(APPLICATION->getThemedIcon("centralmods"));
@@ -64,6 +64,25 @@ void ThemeWizardPage::updateIcons() {
parentWidget()->update();
}
+void ThemeWizardPage::updateCat()
+{
+ qDebug() << "Setting Cat";
+
+ QDateTime now = QDateTime::currentDateTime();
+ QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
+ QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
+ QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
+ QString cat = APPLICATION->settings()->get("BackgroundCat").toString();
+ if (std::abs(now.daysTo(xmas)) <= 4) {
+ cat += "-xmas";
+ } else if (std::abs(now.daysTo(halloween)) <= 4) {
+ cat += "-spooky";
+ } else if (std::abs(now.daysTo(birthday)) <= 12) {
+ cat += "-bday";
+ }
+ ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(cat)));
+}
+
void ThemeWizardPage::retranslate()
{
ui->retranslateUi(this);
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h
index 10913d1b..6562ad2e 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.h
+++ b/launcher/ui/setupwizard/ThemeWizardPage.h
@@ -38,6 +38,7 @@ public:
private slots:
void updateIcons();
+ void updateCat();
private:
Ui::ThemeWizardPage *ui;
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.ui b/launcher/ui/setupwizard/ThemeWizardPage.ui
index b743644f..95b0f805 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.ui
+++ b/launcher/ui/setupwizard/ThemeWizardPage.ui
@@ -6,8 +6,8 @@
0
0
- 400
- 300
+ 510
+ 552
@@ -309,6 +309,28 @@
+ -
+
+
+
+ 0
+ 256
+
+
+
+
+
+
+
+ 256
+ 256
+
+
+
+ true
+
+
+
-
diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp
index 3ad61668..198e76ba 100644
--- a/launcher/ui/themes/CustomTheme.cpp
+++ b/launcher/ui/themes/CustomTheme.cpp
@@ -167,8 +167,6 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest
if (!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) {
themeWarningLog() << "couldn't create folder for theme!";
- m_palette = baseTheme->colorScheme();
- m_styleSheet = baseTheme->appStyleSheet();
return;
}
@@ -177,18 +175,15 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest
bool jsonDataIncomplete = false;
m_palette = baseTheme->colorScheme();
- if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath, jsonDataIncomplete)) {
- themeDebugLog() << "Did not read theme json file correctly, writing new one to: " << themeFilePath;
- m_name = "Custom";
- m_palette = baseTheme->colorScheme();
- m_fadeColor = baseTheme->fadeColor();
- m_fadeAmount = baseTheme->fadeAmount();
- m_widgets = baseTheme->qtTheme();
- m_qssFilePath = "themeStyle.css";
- } else {
+ if (readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath, jsonDataIncomplete)) {
+ // If theme data was found, fade "Disabled" color of each role according to FadeAmount
m_palette = fadeInactive(m_palette, m_fadeAmount, m_fadeColor);
+ } else {
+ themeDebugLog() << "Did not read theme json file correctly, not changing theme, keeping previous.";
+ return;
}
+ // FIXME: This is kinda jank, it only actually checks if the qss file path is not present. It should actually check for any relevant missing data (e.g. name, colors)
if (jsonDataIncomplete) {
writeThemeJson(fileInfo.absoluteFilePath(), m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath);
}
@@ -197,20 +192,14 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest
QFileInfo info(qssFilePath);
if (info.isFile()) {
try {
- // TODO: validate css?
+ // TODO: validate qss?
m_styleSheet = QString::fromUtf8(FS::read(qssFilePath));
} catch (const Exception& e) {
- themeWarningLog() << "Couldn't load css:" << e.cause() << "from" << qssFilePath;
- m_styleSheet = baseTheme->appStyleSheet();
+ themeWarningLog() << "Couldn't load qss:" << e.cause() << "from" << qssFilePath;
+ return;
}
} else {
- themeDebugLog() << "No theme css present.";
- m_styleSheet = baseTheme->appStyleSheet();
- try {
- FS::write(qssFilePath, m_styleSheet.toUtf8());
- } catch (const Exception& e) {
- themeWarningLog() << "Couldn't write css:" << e.cause() << "to" << qssFilePath;
- }
+ themeDebugLog() << "No theme qss present.";
}
} else {
m_id = fileInfo.fileName();
diff --git a/launcher/ui/themes/ITheme.h b/launcher/ui/themes/ITheme.h
index bb5c8afe..2e5b7f25 100644
--- a/launcher/ui/themes/ITheme.h
+++ b/launcher/ui/themes/ITheme.h
@@ -33,14 +33,13 @@
* limitations under the License.
*/
#pragma once
-#include
#include
+#include
class QStyle;
-class ITheme
-{
-public:
+class ITheme {
+ public:
virtual ~ITheme() {}
virtual void apply();
virtual QString id() = 0;
@@ -52,10 +51,7 @@ public:
virtual QPalette colorScheme() = 0;
virtual QColor fadeColor() = 0;
virtual double fadeAmount() = 0;
- virtual QStringList searchPaths()
- {
- return {};
- }
+ virtual QStringList searchPaths() { return {}; }
static QPalette fadeInactive(QPalette in, qreal bias, QColor color);
};
diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp
index d6ef442b..24875e33 100644
--- a/launcher/ui/themes/SystemTheme.cpp
+++ b/launcher/ui/themes/SystemTheme.cpp
@@ -34,24 +34,22 @@
*/
#include "SystemTheme.h"
#include
+#include
#include
#include
-#include
#include "ThemeManager.h"
SystemTheme::SystemTheme()
{
themeDebugLog() << "Determining System Theme...";
- const auto & style = QApplication::style();
+ const auto& style = QApplication::style();
systemPalette = style->standardPalette();
QString lowerThemeName = style->objectName();
themeDebugLog() << "System theme seems to be:" << lowerThemeName;
QStringList styles = QStyleFactory::keys();
- for(auto &st: styles)
- {
+ for (auto& st : styles) {
themeDebugLog() << "Considering theme from theme factory:" << st.toLower();
- if(st.toLower() == lowerThemeName)
- {
+ if (st.toLower() == lowerThemeName) {
systemTheme = st;
themeDebugLog() << "System theme has been determined to be:" << systemTheme;
return;
@@ -99,7 +97,7 @@ double SystemTheme::fadeAmount()
QColor SystemTheme::fadeColor()
{
- return QColor(128,128,128);
+ return QColor(128, 128, 128);
}
bool SystemTheme::hasStyleSheet()
diff --git a/launcher/ui/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h
index 5c9216eb..b5c03def 100644
--- a/launcher/ui/themes/SystemTheme.h
+++ b/launcher/ui/themes/SystemTheme.h
@@ -36,9 +36,8 @@
#include "ITheme.h"
-class SystemTheme: public ITheme
-{
-public:
+class SystemTheme : public ITheme {
+ public:
SystemTheme();
virtual ~SystemTheme() {}
void apply() override;
@@ -52,7 +51,8 @@ public:
QPalette colorScheme() override;
double fadeAmount() override;
QColor fadeColor() override;
-private:
+
+ private:
QPalette systemPalette;
QString systemTheme;
};
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index 0a70ddfc..bb10cd48 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -35,9 +35,6 @@ class ThemeManager {
public:
ThemeManager(MainWindow* mainWindow);
- // maybe make private? Or put in ctor?
- void InitializeThemes();
-
QList getValidApplicationThemes();
void setIconTheme(const QString& name);
void applyCurrentlySelectedTheme();
@@ -48,6 +45,7 @@ class ThemeManager {
MainWindow* m_mainWindow;
bool m_firstThemeInitialized;
+ void InitializeThemes();
QString AddTheme(std::unique_ptr theme);
ITheme* GetTheme(QString themeId);
};
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
index 0830a030..eafcf482 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
@@ -36,18 +36,40 @@ ThemeCustomizationWidget::~ThemeCustomizationWidget()
delete ui;
}
+///
+/// The layout was not quite right, so currently this just disables the UI elements, which should be hidden instead
+/// TODO FIXME
+///
+/// Original Method One:
+/// ui->iconsComboBox->setVisible(features& ThemeFields::ICONS);
+/// ui->iconsLabel->setVisible(features& ThemeFields::ICONS);
+/// ui->widgetStyleComboBox->setVisible(features& ThemeFields::WIDGETS);
+/// ui->widgetThemeLabel->setVisible(features& ThemeFields::WIDGETS);
+/// ui->backgroundCatComboBox->setVisible(features& ThemeFields::CAT);
+/// ui->backgroundCatLabel->setVisible(features& ThemeFields::CAT);
+///
+/// original Method Two:
+/// if (!(features & ThemeFields::ICONS)) {
+/// ui->formLayout->setRowVisible(0, false);
+/// }
+/// if (!(features & ThemeFields::WIDGETS)) {
+/// ui->formLayout->setRowVisible(1, false);
+/// }
+/// if (!(features & ThemeFields::CAT)) {
+/// ui->formLayout->setRowVisible(2, false);
+/// }
+///
+///
void ThemeCustomizationWidget::showFeatures(ThemeFields features) {
- ui->iconsComboBox->setVisible(features & ThemeFields::ICONS);
- ui->iconsLabel->setVisible(features & ThemeFields::ICONS);
- ui->widgetStyleComboBox->setVisible(features & ThemeFields::WIDGETS);
- ui->widgetThemeLabel->setVisible(features & ThemeFields::WIDGETS);
- ui->backgroundCatComboBox->setVisible(features & ThemeFields::CAT);
- ui->backgroundCatLabel->setVisible(features & ThemeFields::CAT);
+ ui->iconsComboBox->setEnabled(features & ThemeFields::ICONS);
+ ui->iconsLabel->setEnabled(features & ThemeFields::ICONS);
+ ui->widgetStyleComboBox->setEnabled(features & ThemeFields::WIDGETS);
+ ui->widgetThemeLabel->setEnabled(features & ThemeFields::WIDGETS);
+ ui->backgroundCatComboBox->setEnabled(features & ThemeFields::CAT);
+ ui->backgroundCatLabel->setEnabled(features & ThemeFields::CAT);
}
void ThemeCustomizationWidget::applyIconTheme(int index) {
- emit currentIconThemeChanged(index);
-
auto settings = APPLICATION->settings();
auto original = settings->get("IconTheme").toString();
// FIXME: make generic
@@ -56,11 +78,11 @@ void ThemeCustomizationWidget::applyIconTheme(int index) {
if (original != settings->get("IconTheme")) {
APPLICATION->applyCurrentlySelectedTheme();
}
+
+ emit currentIconThemeChanged(index);
}
void ThemeCustomizationWidget::applyWidgetTheme(int index) {
- emit currentWidgetThemeChanged(index);
-
auto settings = APPLICATION->settings();
auto originalAppTheme = settings->get("ApplicationTheme").toString();
auto newAppTheme = ui->widgetStyleComboBox->currentData().toString();
@@ -68,26 +90,15 @@ void ThemeCustomizationWidget::applyWidgetTheme(int index) {
settings->set("ApplicationTheme", newAppTheme);
APPLICATION->applyCurrentlySelectedTheme();
}
+
+ emit currentWidgetThemeChanged(index);
}
void ThemeCustomizationWidget::applyCatTheme(int index) {
- emit currentCatChanged(index);
-
auto settings = APPLICATION->settings();
- switch (index) {
- case 0: // original cat
- settings->set("BackgroundCat", "kitteh");
- break;
- case 1: // rory the cat
- settings->set("BackgroundCat", "rory");
- break;
- case 2: // rory the cat flat edition
- settings->set("BackgroundCat", "rory-flat");
- break;
- case 3: // teawie
- settings->set("BackgroundCat", "teawie");
- break;
- }
+ settings->set("BackgroundCat", m_catOptions[index]);
+
+ emit currentCatChanged(index);
}
void ThemeCustomizationWidget::applySettings()
@@ -101,8 +112,8 @@ void ThemeCustomizationWidget::loadSettings()
auto settings = APPLICATION->settings();
// FIXME: make generic
- auto theme = settings->get("IconTheme").toString();
- ui->iconsComboBox->setCurrentIndex(m_iconThemeOptions.indexOf(theme));
+ auto iconTheme = settings->get("IconTheme").toString();
+ ui->iconsComboBox->setCurrentIndex(m_iconThemeOptions.indexOf(iconTheme));
{
auto currentTheme = settings->get("ApplicationTheme").toString();
@@ -118,18 +129,10 @@ void ThemeCustomizationWidget::loadSettings()
}
auto cat = settings->get("BackgroundCat").toString();
- if (cat == "kitteh") {
- ui->backgroundCatComboBox->setCurrentIndex(0);
- } else if (cat == "rory") {
- ui->backgroundCatComboBox->setCurrentIndex(1);
- } else if (cat == "rory-flat") {
- ui->backgroundCatComboBox->setCurrentIndex(2);
- } else if (cat == "teawie") {
- ui->backgroundCatComboBox->setCurrentIndex(3);
- }
+ ui->backgroundCatComboBox->setCurrentIndex(m_catOptions.indexOf(cat));
}
void ThemeCustomizationWidget::retranslate()
{
ui->retranslateUi(this);
-}
\ No newline at end of file
+}
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h
index e17286e1..653e89e7 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.h
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.h
@@ -61,4 +61,5 @@ signals:
private:
QStringList m_iconThemeOptions{ "pe_colored", "pe_light", "pe_dark", "pe_blue", "breeze_light", "breeze_dark", "OSX", "iOS", "flat", "flat_white", "multimc", "custom" };
+ QStringList m_catOptions{ "kitteh", "rory", "rory-flat" };
};
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui
index c184b8f3..9cc5cc76 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.ui
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.ui
@@ -11,9 +11,12 @@
- Form
+ Form
+
+ QLayout::SetMinimumSize
+
0
--
cgit
From 6daa45783894fc7517917d6f6df0deaac1a41ba3 Mon Sep 17 00:00:00 2001
From: Tayou
Date: Mon, 9 Jan 2023 16:58:27 +0100
Subject: Implement Suggestions from flow & Scrumplex
Signed-off-by: Tayou
---
launcher/Application.cpp | 7 ++-
launcher/ui/MainWindow.cpp | 22 ++-----
launcher/ui/setupwizard/ThemeWizardPage.cpp | 27 ++------
launcher/ui/setupwizard/ThemeWizardPage.h | 16 +++--
launcher/ui/themes/ThemeManager.cpp | 35 ++++++++---
launcher/ui/themes/ThemeManager.h | 9 +--
launcher/ui/widgets/ThemeCustomizationWidget.cpp | 22 +++++--
launcher/ui/widgets/ThemeCustomizationWidget.h | 50 +++++++++------
launcher/ui/widgets/ThemeCustomizationWidget.ui | 80 ------------------------
9 files changed, 97 insertions(+), 171 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 3e64b74f..f2cc7bfb 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -498,7 +498,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Theming
m_settings->registerSetting("IconTheme", QString("pe_colored"));
- m_settings->registerSetting("ApplicationTheme", QString("system"));
+ m_settings->registerSetting("ApplicationTheme");
m_settings->registerSetting("BackgroundCat", QString("kitteh"));
// Remembered state
@@ -890,8 +890,8 @@ bool Application::createSetupWizard()
return false;
}();
bool pasteInterventionRequired = settings()->get("PastebinURL") != "";
- bool themeInterventionRequired = settings()->get("ApplicationTheme") != "";
- bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired;
+ bool themeInterventionRequired = settings()->get("ApplicationTheme") == "";
+ bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired || themeInterventionRequired;
if(wizardRequired)
{
@@ -913,6 +913,7 @@ bool Application::createSetupWizard()
if (themeInterventionRequired)
{
+ settings()->set("ApplicationTheme", QString("system")); // set default theme after going into theme wizard
m_setupWizard->addPage(new ThemeWizardPage(m_setupWizard));
}
connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished);
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index a921e378..ab80fb80 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -111,6 +111,7 @@
#include "ui/dialogs/ExportInstanceDialog.h"
#include "ui/dialogs/ImportResourcePackDialog.h"
#include "ui/themes/ITheme.h"
+#include "ui/themes/ThemeManager.h"
#include
#include
@@ -1654,20 +1655,7 @@ void MainWindow::onCatToggled(bool state)
void MainWindow::setCatBackground(bool enabled)
{
- if (enabled)
- {
- QDateTime now = QDateTime::currentDateTime();
- QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
- QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
- QString cat = APPLICATION->settings()->get("BackgroundCat").toString();
- if (std::abs(now.daysTo(xmas)) <= 4) {
- cat += "-xmas";
- } else if (std::abs(now.daysTo(halloween)) <= 4) {
- cat += "-spooky";
- } else if (std::abs(now.daysTo(birthday)) <= 12) {
- cat += "-bday";
- }
+ if (enabled) {
view->setStyleSheet(QString(R"(
InstanceView
{
@@ -1678,10 +1666,8 @@ InstanceView
background-repeat: none;
background-color:palette(base);
})")
- .arg(cat));
- }
- else
- {
+ .arg(ThemeManager::getCatImage()));
+ } else {
view->setStyleSheet(QString());
}
}
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp
index 4e1eb488..cc2d335b 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.cpp
+++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp
@@ -20,6 +20,7 @@
#include "Application.h"
#include "ui/themes/ITheme.h"
+#include "ui/themes/ThemeManager.h"
#include "ui/widgets/ThemeCustomizationWidget.h"
#include "ui_ThemeCustomizationWidget.h"
@@ -27,8 +28,8 @@ ThemeWizardPage::ThemeWizardPage(QWidget* parent) : BaseWizardPage(parent), ui(n
{
ui->setupUi(this);
- connect(ui->themeCustomizationWidget, QOverload::of(&ThemeCustomizationWidget::currentIconThemeChanged), this, &ThemeWizardPage::updateIcons);
- connect(ui->themeCustomizationWidget, QOverload::of(&ThemeCustomizationWidget::currentCatChanged), this, &ThemeWizardPage::updateCat);
+ connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentIconThemeChanged, this, &ThemeWizardPage::updateIcons);
+ connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentCatChanged, this, &ThemeWizardPage::updateCat);
updateIcons();
updateCat();
@@ -39,13 +40,6 @@ ThemeWizardPage::~ThemeWizardPage()
delete ui;
}
-void ThemeWizardPage::initializePage() {}
-
-bool ThemeWizardPage::validatePage()
-{
- return true;
-}
-
void ThemeWizardPage::updateIcons()
{
qDebug() << "Setting Icons";
@@ -67,20 +61,7 @@ void ThemeWizardPage::updateIcons()
void ThemeWizardPage::updateCat()
{
qDebug() << "Setting Cat";
-
- QDateTime now = QDateTime::currentDateTime();
- QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
- QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
- QString cat = APPLICATION->settings()->get("BackgroundCat").toString();
- if (std::abs(now.daysTo(xmas)) <= 4) {
- cat += "-xmas";
- } else if (std::abs(now.daysTo(halloween)) <= 4) {
- cat += "-spooky";
- } else if (std::abs(now.daysTo(birthday)) <= 12) {
- cat += "-bday";
- }
- ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(cat)));
+ ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(ThemeManager::getCatImage())));
}
void ThemeWizardPage::retranslate()
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h
index 6562ad2e..992ba2ca 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.h
+++ b/launcher/ui/setupwizard/ThemeWizardPage.h
@@ -24,22 +24,20 @@ namespace Ui {
class ThemeWizardPage;
}
-class ThemeWizardPage : public BaseWizardPage
-{
+class ThemeWizardPage : public BaseWizardPage {
Q_OBJECT
-public:
- explicit ThemeWizardPage(QWidget *parent = nullptr);
+ public:
+ explicit ThemeWizardPage(QWidget* parent = nullptr);
~ThemeWizardPage();
- void initializePage() override;
- bool validatePage() override;
+ bool validatePage() override { return true; };
void retranslate() override;
-private slots:
+ private slots:
void updateIcons();
void updateCat();
-private:
- Ui::ThemeWizardPage *ui;
+ private:
+ Ui::ThemeWizardPage* ui;
};
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index a6cebc6f..44c13f40 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -31,13 +31,13 @@
ThemeManager::ThemeManager(MainWindow* mainWindow)
{
m_mainWindow = mainWindow;
- InitializeThemes();
+ initializeThemes();
}
/// @brief Adds the Theme to the list of themes
/// @param theme The Theme to add
/// @return Theme ID
-QString ThemeManager::AddTheme(std::unique_ptr theme)
+QString ThemeManager::addTheme(std::unique_ptr theme)
{
QString id = theme->id();
m_themes.emplace(id, std::move(theme));
@@ -47,12 +47,12 @@ QString ThemeManager::AddTheme(std::unique_ptr theme)
/// @brief Gets the Theme from the List via ID
/// @param themeId Theme ID of theme to fetch
/// @return Theme at themeId
-ITheme* ThemeManager::GetTheme(QString themeId)
+ITheme* ThemeManager::getTheme(QString themeId)
{
return m_themes[themeId].get();
}
-void ThemeManager::InitializeThemes()
+void ThemeManager::initializeThemes()
{
// Icon themes
{
@@ -67,10 +67,10 @@ void ThemeManager::InitializeThemes()
// Initialize widget themes
{
themeDebugLog() << "<> Initializing Widget Themes";
- themeDebugLog() << "Loading Built-in Theme:" << AddTheme(std::make_unique());
- auto darkThemeId = AddTheme(std::make_unique());
+ themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+ auto darkThemeId = addTheme(std::make_unique());
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
- themeDebugLog() << "Loading Built-in Theme:" << AddTheme(std::make_unique());
+ themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
// TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
// dropdown?)
@@ -84,7 +84,7 @@ void ThemeManager::InitializeThemes()
if (themeJson.exists()) {
// Load "theme.json" based themes
themeDebugLog() << "Loading JSON Theme from:" << themeJson.absoluteFilePath();
- AddTheme(std::make_unique(GetTheme(darkThemeId), themeJson, true));
+ addTheme(std::make_unique(getTheme(darkThemeId), themeJson, true));
} else {
// Load pure QSS Themes
QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), { "*.qss", "*.css" }, QDir::Files);
@@ -92,7 +92,7 @@ void ThemeManager::InitializeThemes()
QFile customThemeFile(stylesheetFileIterator.next());
QFileInfo customThemeFileInfo(customThemeFile);
themeDebugLog() << "Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath();
- AddTheme(std::make_unique(GetTheme(darkThemeId), customThemeFileInfo, false));
+ addTheme(std::make_unique(getTheme(darkThemeId), customThemeFileInfo, false));
}
}
}
@@ -136,3 +136,20 @@ void ThemeManager::setApplicationTheme(const QString& name)
themeWarningLog() << "Tried to set invalid theme:" << name;
}
}
+
+QString ThemeManager::getCatImage(QString catName)
+{
+ QDateTime now = QDateTime::currentDateTime();
+ QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
+ QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
+ QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
+ QString cat = catName == "" ? APPLICATION->settings()->get("BackgroundCat").toString() : catName;
+ if (std::abs(now.daysTo(xmas)) <= 4) {
+ cat += "-xmas";
+ } else if (std::abs(now.daysTo(halloween)) <= 4) {
+ cat += "-spooky";
+ } else if (std::abs(now.daysTo(birthday)) <= 12) {
+ cat += "-bday";
+ }
+ return cat;
+}
\ No newline at end of file
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index bb10cd48..4f36bffa 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -40,12 +40,13 @@ class ThemeManager {
void applyCurrentlySelectedTheme();
void setApplicationTheme(const QString& name);
+ static QString getCatImage(QString catName = "");
+
private:
std::map> m_themes;
MainWindow* m_mainWindow;
- bool m_firstThemeInitialized;
- void InitializeThemes();
- QString AddTheme(std::unique_ptr theme);
- ITheme* GetTheme(QString themeId);
+ void initializeThemes();
+ QString addTheme(std::unique_ptr theme);
+ ITheme* getTheme(QString themeId);
};
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
index eafcf482..5fb5bd4e 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
@@ -20,6 +20,7 @@
#include "Application.h"
#include "ui/themes/ITheme.h"
+#include "ui/themes/ThemeManager.h"
ThemeCustomizationWidget::ThemeCustomizationWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ThemeCustomizationWidget)
{
@@ -72,8 +73,7 @@ void ThemeCustomizationWidget::showFeatures(ThemeFields features) {
void ThemeCustomizationWidget::applyIconTheme(int index) {
auto settings = APPLICATION->settings();
auto original = settings->get("IconTheme").toString();
- // FIXME: make generic
- settings->set("IconTheme", m_iconThemeOptions[index]);
+ settings->set("IconTheme", m_iconThemeOptions[index].first);
if (original != settings->get("IconTheme")) {
APPLICATION->applyCurrentlySelectedTheme();
@@ -96,7 +96,7 @@ void ThemeCustomizationWidget::applyWidgetTheme(int index) {
void ThemeCustomizationWidget::applyCatTheme(int index) {
auto settings = APPLICATION->settings();
- settings->set("BackgroundCat", m_catOptions[index]);
+ settings->set("BackgroundCat", m_catOptions[index].first);
emit currentCatChanged(index);
}
@@ -111,9 +111,13 @@ void ThemeCustomizationWidget::loadSettings()
{
auto settings = APPLICATION->settings();
- // FIXME: make generic
auto iconTheme = settings->get("IconTheme").toString();
- ui->iconsComboBox->setCurrentIndex(m_iconThemeOptions.indexOf(iconTheme));
+ for (auto& iconThemeFromList : m_iconThemeOptions) {
+ ui->iconsComboBox->addItem(QIcon(QString(":/icons/%1/scalable/settings").arg(iconThemeFromList.first)), iconThemeFromList.second);
+ if (iconTheme == iconThemeFromList.first) {
+ ui->iconsComboBox->setCurrentIndex(ui->iconsComboBox->count() - 1);
+ }
+ }
{
auto currentTheme = settings->get("ApplicationTheme").toString();
@@ -129,7 +133,13 @@ void ThemeCustomizationWidget::loadSettings()
}
auto cat = settings->get("BackgroundCat").toString();
- ui->backgroundCatComboBox->setCurrentIndex(m_catOptions.indexOf(cat));
+ for (auto& catFromList : m_catOptions) {
+ ui->backgroundCatComboBox->addItem(QIcon(QString(":/backgrounds/%1").arg(ThemeManager::getCatImage(catFromList.first))),
+ catFromList.second);
+ if (cat == catFromList.first) {
+ ui->backgroundCatComboBox->setCurrentIndex(ui->backgroundCatComboBox->count() - 1);
+ }
+ }
}
void ThemeCustomizationWidget::retranslate()
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.h b/launcher/ui/widgets/ThemeCustomizationWidget.h
index 653e89e7..d450e8df 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.h
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.h
@@ -18,25 +18,19 @@
#pragma once
#include
-#include
+#include "translations/TranslationsModel.h"
-enum ThemeFields {
- NONE = 0b0000,
- ICONS = 0b0001,
- WIDGETS = 0b0010,
- CAT = 0b0100
-};
+enum ThemeFields { NONE = 0b0000, ICONS = 0b0001, WIDGETS = 0b0010, CAT = 0b0100 };
namespace Ui {
class ThemeCustomizationWidget;
}
-class ThemeCustomizationWidget : public QWidget
-{
+class ThemeCustomizationWidget : public QWidget {
Q_OBJECT
-public:
- explicit ThemeCustomizationWidget(QWidget *parent = nullptr);
+ public:
+ explicit ThemeCustomizationWidget(QWidget* parent = nullptr);
~ThemeCustomizationWidget();
void showFeatures(ThemeFields features);
@@ -45,21 +39,39 @@ public:
void loadSettings();
void retranslate();
-
- Ui::ThemeCustomizationWidget *ui;
-private slots:
+ private slots:
void applyIconTheme(int index);
void applyWidgetTheme(int index);
void applyCatTheme(int index);
-signals:
+ signals:
int currentIconThemeChanged(int index);
int currentWidgetThemeChanged(int index);
int currentCatChanged(int index);
-private:
+ private:
+ Ui::ThemeCustomizationWidget* ui;
- QStringList m_iconThemeOptions{ "pe_colored", "pe_light", "pe_dark", "pe_blue", "breeze_light", "breeze_dark", "OSX", "iOS", "flat", "flat_white", "multimc", "custom" };
- QStringList m_catOptions{ "kitteh", "rory", "rory-flat" };
-};
+ //TODO finish implementing
+ QList> m_iconThemeOptions{
+ { "pe_colored", QObject::tr("Simple (Colored Icons)") },
+ { "pe_light", QObject::tr("Simple (Light Icons)") },
+ { "pe_dark", QObject::tr("Simple (Dark Icons)") },
+ { "pe_blue", QObject::tr("Simple (Blue Icons)") },
+ { "breeze_light", QObject::tr("Breeze Light") },
+ { "breeze_dark", QObject::tr("Breeze Dark") },
+ { "OSX", QObject::tr("OSX") },
+ { "iOS", QObject::tr("iOS") },
+ { "flat", QObject::tr("Flat") },
+ { "flat_white", QObject::tr("Flat (White)") },
+ { "multimc", QObject::tr("Legacy") },
+ { "custom", QObject::tr("Custom") }
+ };
+ QList> m_catOptions{
+ { "kitteh", QObject::tr("Background Cat (from MultiMC)") },
+ { "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") },
+ { "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") },
+ { "teawie", QObject::tr("Teawie (drawn by SympathyTea)") }
+ };
+};
\ No newline at end of file
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.ui b/launcher/ui/widgets/ThemeCustomizationWidget.ui
index 9cc5cc76..15ba831e 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.ui
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.ui
@@ -50,66 +50,6 @@
Qt::StrongFocus
-
-
-
- Simple (Colored Icons)
-
-
- -
-
- Simple (Light Icons)
-
-
- -
-
- Simple (Dark Icons)
-
-
- -
-
- Simple (Blue Icons)
-
-
- -
-
- Breeze Light
-
-
- -
-
- Breeze Dark
-
-
- -
-
- OSX
-
-
- -
-
- iOS
-
-
- -
-
- Flat
-
-
- -
-
- Flat (White)
-
-
- -
-
- Legacy
-
-
- -
-
- Custom
-
-
-
@@ -156,26 +96,6 @@
Qt::StrongFocus
-
-
-
- Background Cat (from MultiMC)
-
-
- -
-
- Rory ID 11 (drawn by Ashtaka)
-
-
- -
-
- Rory ID 11 (flat edition, drawn by Ashtaka)
-
-
- -
-
- Teawie (drawn by SympathyTea)
-
-
--
cgit
From 7d440402ade59fd38b6f1d6b70fb51449cc57e5d Mon Sep 17 00:00:00 2001
From: Tayou <31988415+TayouVR@users.noreply.github.com>
Date: Wed, 4 Jan 2023 14:30:25 +0100
Subject: Update launcher/Application.cpp with suggestion from scrumplex
Co-authored-by: Sefa Eyeoglu
Signed-off-by: Tayou
---
launcher/Application.cpp | 2 +-
launcher/ui/themes/ThemeManager.cpp | 4 ++--
launcher/ui/themes/ThemeManager.h | 5 +++++
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index f2cc7bfb..ed8d8d2c 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -498,7 +498,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Theming
m_settings->registerSetting("IconTheme", QString("pe_colored"));
- m_settings->registerSetting("ApplicationTheme");
+ m_settings->registerSetting("ApplicationTheme", QString());
m_settings->registerSetting("BackgroundCat", QString("kitteh"));
// Remembered state
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 44c13f40..7ccc946a 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -143,7 +143,7 @@ QString ThemeManager::getCatImage(QString catName)
QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
- QString cat = catName == "" ? APPLICATION->settings()->get("BackgroundCat").toString() : catName;
+ QString cat = !catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString();
if (std::abs(now.daysTo(xmas)) <= 4) {
cat += "-xmas";
} else if (std::abs(now.daysTo(halloween)) <= 4) {
@@ -152,4 +152,4 @@ QString ThemeManager::getCatImage(QString catName)
cat += "-bday";
}
return cat;
-}
\ No newline at end of file
+}
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index 4f36bffa..d5e73bb8 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -40,6 +40,11 @@ class ThemeManager {
void applyCurrentlySelectedTheme();
void setApplicationTheme(const QString& name);
+ ///
+ /// Returns the cat based on selected cat and with events (Birthday, XMas, etc.)
+ ///
+ /// Optional, if you need a specific cat.
+ ///
static QString getCatImage(QString catName = "");
private:
--
cgit
From 689fe1e2c76b8065b9769b4304b1c9b4d81215b1 Mon Sep 17 00:00:00 2001
From: Tayou
Date: Mon, 9 Jan 2023 17:01:33 +0100
Subject: CRLF -> LF
damn you visual studio for creating CRLF files everywhere...
Signed-off-by: Tayou
---
launcher/ui/setupwizard/ThemeWizardPage.cpp | 140 ++---
launcher/ui/setupwizard/ThemeWizardPage.h | 86 +--
launcher/ui/setupwizard/ThemeWizardPage.ui | 716 +++++++++++------------
launcher/ui/themes/ThemeManager.cpp | 310 +++++-----
launcher/ui/themes/ThemeManager.h | 114 ++--
launcher/ui/widgets/ThemeCustomizationWidget.cpp | 296 +++++-----
launcher/ui/widgets/ThemeCustomizationWidget.h | 152 ++---
launcher/ui/widgets/ThemeCustomizationWidget.ui | 210 +++----
8 files changed, 1012 insertions(+), 1012 deletions(-)
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.cpp b/launcher/ui/setupwizard/ThemeWizardPage.cpp
index cc2d335b..42826aba 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.cpp
+++ b/launcher/ui/setupwizard/ThemeWizardPage.cpp
@@ -1,70 +1,70 @@
-// SPDX-License-Identifier: GPL-3.0-only
-/*
- * Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
- *
- * 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 .
- */
-#include "ThemeWizardPage.h"
-#include "ui_ThemeWizardPage.h"
-
-#include "Application.h"
-#include "ui/themes/ITheme.h"
-#include "ui/themes/ThemeManager.h"
-#include "ui/widgets/ThemeCustomizationWidget.h"
-#include "ui_ThemeCustomizationWidget.h"
-
-ThemeWizardPage::ThemeWizardPage(QWidget* parent) : BaseWizardPage(parent), ui(new Ui::ThemeWizardPage)
-{
- ui->setupUi(this);
-
- connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentIconThemeChanged, this, &ThemeWizardPage::updateIcons);
- connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentCatChanged, this, &ThemeWizardPage::updateCat);
-
- updateIcons();
- updateCat();
-}
-
-ThemeWizardPage::~ThemeWizardPage()
-{
- delete ui;
-}
-
-void ThemeWizardPage::updateIcons()
-{
- qDebug() << "Setting Icons";
- ui->previewIconButton0->setIcon(APPLICATION->getThemedIcon("new"));
- ui->previewIconButton1->setIcon(APPLICATION->getThemedIcon("centralmods"));
- ui->previewIconButton2->setIcon(APPLICATION->getThemedIcon("viewfolder"));
- ui->previewIconButton3->setIcon(APPLICATION->getThemedIcon("launch"));
- ui->previewIconButton4->setIcon(APPLICATION->getThemedIcon("copy"));
- ui->previewIconButton5->setIcon(APPLICATION->getThemedIcon("export"));
- ui->previewIconButton6->setIcon(APPLICATION->getThemedIcon("delete"));
- ui->previewIconButton7->setIcon(APPLICATION->getThemedIcon("about"));
- ui->previewIconButton8->setIcon(APPLICATION->getThemedIcon("settings"));
- ui->previewIconButton9->setIcon(APPLICATION->getThemedIcon("cat"));
- update();
- repaint();
- parentWidget()->update();
-}
-
-void ThemeWizardPage::updateCat()
-{
- qDebug() << "Setting Cat";
- ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(ThemeManager::getCatImage())));
-}
-
-void ThemeWizardPage::retranslate()
-{
- ui->retranslateUi(this);
-}
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#include "ThemeWizardPage.h"
+#include "ui_ThemeWizardPage.h"
+
+#include "Application.h"
+#include "ui/themes/ITheme.h"
+#include "ui/themes/ThemeManager.h"
+#include "ui/widgets/ThemeCustomizationWidget.h"
+#include "ui_ThemeCustomizationWidget.h"
+
+ThemeWizardPage::ThemeWizardPage(QWidget* parent) : BaseWizardPage(parent), ui(new Ui::ThemeWizardPage)
+{
+ ui->setupUi(this);
+
+ connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentIconThemeChanged, this, &ThemeWizardPage::updateIcons);
+ connect(ui->themeCustomizationWidget, &ThemeCustomizationWidget::currentCatChanged, this, &ThemeWizardPage::updateCat);
+
+ updateIcons();
+ updateCat();
+}
+
+ThemeWizardPage::~ThemeWizardPage()
+{
+ delete ui;
+}
+
+void ThemeWizardPage::updateIcons()
+{
+ qDebug() << "Setting Icons";
+ ui->previewIconButton0->setIcon(APPLICATION->getThemedIcon("new"));
+ ui->previewIconButton1->setIcon(APPLICATION->getThemedIcon("centralmods"));
+ ui->previewIconButton2->setIcon(APPLICATION->getThemedIcon("viewfolder"));
+ ui->previewIconButton3->setIcon(APPLICATION->getThemedIcon("launch"));
+ ui->previewIconButton4->setIcon(APPLICATION->getThemedIcon("copy"));
+ ui->previewIconButton5->setIcon(APPLICATION->getThemedIcon("export"));
+ ui->previewIconButton6->setIcon(APPLICATION->getThemedIcon("delete"));
+ ui->previewIconButton7->setIcon(APPLICATION->getThemedIcon("about"));
+ ui->previewIconButton8->setIcon(APPLICATION->getThemedIcon("settings"));
+ ui->previewIconButton9->setIcon(APPLICATION->getThemedIcon("cat"));
+ update();
+ repaint();
+ parentWidget()->update();
+}
+
+void ThemeWizardPage::updateCat()
+{
+ qDebug() << "Setting Cat";
+ ui->catImagePreviewButton->setIcon(QIcon(QString(R"(:/backgrounds/%1)").arg(ThemeManager::getCatImage())));
+}
+
+void ThemeWizardPage::retranslate()
+{
+ ui->retranslateUi(this);
+}
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.h b/launcher/ui/setupwizard/ThemeWizardPage.h
index 992ba2ca..61a3d0c0 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.h
+++ b/launcher/ui/setupwizard/ThemeWizardPage.h
@@ -1,43 +1,43 @@
-// SPDX-License-Identifier: GPL-3.0-only
-/*
- * Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
- *
- * 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 .
- */
-#pragma once
-
-#include
-#include "BaseWizardPage.h"
-
-namespace Ui {
-class ThemeWizardPage;
-}
-
-class ThemeWizardPage : public BaseWizardPage {
- Q_OBJECT
-
- public:
- explicit ThemeWizardPage(QWidget* parent = nullptr);
- ~ThemeWizardPage();
-
- bool validatePage() override { return true; };
- void retranslate() override;
-
- private slots:
- void updateIcons();
- void updateCat();
-
- private:
- Ui::ThemeWizardPage* ui;
-};
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#pragma once
+
+#include
+#include "BaseWizardPage.h"
+
+namespace Ui {
+class ThemeWizardPage;
+}
+
+class ThemeWizardPage : public BaseWizardPage {
+ Q_OBJECT
+
+ public:
+ explicit ThemeWizardPage(QWidget* parent = nullptr);
+ ~ThemeWizardPage();
+
+ bool validatePage() override { return true; };
+ void retranslate() override;
+
+ private slots:
+ void updateIcons();
+ void updateCat();
+
+ private:
+ Ui::ThemeWizardPage* ui;
+};
diff --git a/launcher/ui/setupwizard/ThemeWizardPage.ui b/launcher/ui/setupwizard/ThemeWizardPage.ui
index 95b0f805..1ab04fc8 100644
--- a/launcher/ui/setupwizard/ThemeWizardPage.ui
+++ b/launcher/ui/setupwizard/ThemeWizardPage.ui
@@ -1,358 +1,358 @@
-
-
- ThemeWizardPage
-
-
-
- 0
- 0
- 510
- 552
-
-
-
- WizardPage
-
-
- -
-
-
- Select the Theme you wish to use
-
-
-
- -
-
-
-
- 0
- 100
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- Icon Preview:
-
-
-
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- ..
-
-
- false
-
-
- true
-
-
-
-
-
- -
-
-
-
- 0
- 256
-
-
-
-
-
-
-
- 256
- 256
-
-
-
- true
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 193
-
-
-
-
-
-
-
-
- ThemeCustomizationWidget
- QWidget
- ui/widgets/ThemeCustomizationWidget.h
-
-
-
-
-
+
+
+ ThemeWizardPage
+
+
+
+ 0
+ 0
+ 510
+ 552
+
+
+
+ WizardPage
+
+
+ -
+
+
+ Select the Theme you wish to use
+
+
+
+ -
+
+
+
+ 0
+ 100
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Icon Preview:
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 30
+ 30
+
+
+
+
+ ..
+
+
+ false
+
+
+ true
+
+
+
+
+
+ -
+
+
+
+ 0
+ 256
+
+
+
+
+
+
+
+ 256
+ 256
+
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 193
+
+
+
+
+
+
+
+
+ ThemeCustomizationWidget
+ QWidget
+ ui/widgets/ThemeCustomizationWidget.h
+
+
+
+
+
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 7ccc946a..13406485 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -1,155 +1,155 @@
-// SPDX-License-Identifier: GPL-3.0-only
-/*
- * Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
- *
- * 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 .
- */
-#include "ThemeManager.h"
-
-#include
-#include
-#include
-#include
-#include "ui/themes/BrightTheme.h"
-#include "ui/themes/CustomTheme.h"
-#include "ui/themes/DarkTheme.h"
-#include "ui/themes/SystemTheme.h"
-
-#include "Application.h"
-
-ThemeManager::ThemeManager(MainWindow* mainWindow)
-{
- m_mainWindow = mainWindow;
- initializeThemes();
-}
-
-/// @brief Adds the Theme to the list of themes
-/// @param theme The Theme to add
-/// @return Theme ID
-QString ThemeManager::addTheme(std::unique_ptr theme)
-{
- QString id = theme->id();
- m_themes.emplace(id, std::move(theme));
- return id;
-}
-
-/// @brief Gets the Theme from the List via ID
-/// @param themeId Theme ID of theme to fetch
-/// @return Theme at themeId
-ITheme* ThemeManager::getTheme(QString themeId)
-{
- return m_themes[themeId].get();
-}
-
-void ThemeManager::initializeThemes()
-{
- // Icon themes
- {
- // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies!
- // set icon theme search path!
- auto searchPaths = QIcon::themeSearchPaths();
- searchPaths.append("iconthemes");
- QIcon::setThemeSearchPaths(searchPaths);
- themeDebugLog() << "<> Icon themes initialized.";
- }
-
- // Initialize widget themes
- {
- themeDebugLog() << "<> Initializing Widget Themes";
- themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
- auto darkThemeId = addTheme(std::make_unique());
- themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
- themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
-
- // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
- // dropdown?)
- QString themeFolder = QDir("./themes/").absoluteFilePath("");
- themeDebugLog() << "Theme Folder Path: " << themeFolder;
-
- QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
- while (directoryIterator.hasNext()) {
- QDir dir(directoryIterator.next());
- QFileInfo themeJson(dir.absoluteFilePath("theme.json"));
- if (themeJson.exists()) {
- // Load "theme.json" based themes
- themeDebugLog() << "Loading JSON Theme from:" << themeJson.absoluteFilePath();
- addTheme(std::make_unique(getTheme(darkThemeId), themeJson, true));
- } else {
- // Load pure QSS Themes
- QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), { "*.qss", "*.css" }, QDir::Files);
- while (stylesheetFileIterator.hasNext()) {
- QFile customThemeFile(stylesheetFileIterator.next());
- QFileInfo customThemeFileInfo(customThemeFile);
- themeDebugLog() << "Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath();
- addTheme(std::make_unique(getTheme(darkThemeId), customThemeFileInfo, false));
- }
- }
- }
-
- themeDebugLog() << "<> Widget themes initialized.";
- }
-}
-
-QList ThemeManager::getValidApplicationThemes()
-{
- QList ret;
- ret.reserve(m_themes.size());
- for (auto&& [id, theme] : m_themes) {
- ret.append(theme.get());
- }
- return ret;
-}
-
-void ThemeManager::setIconTheme(const QString& name)
-{
- QIcon::setThemeName(name);
-}
-
-void ThemeManager::applyCurrentlySelectedTheme()
-{
- setIconTheme(APPLICATION->settings()->get("IconTheme").toString());
- themeDebugLog() << "<> Icon theme set.";
- setApplicationTheme(APPLICATION->settings()->get("ApplicationTheme").toString());
- themeDebugLog() << "<> Application theme set.";
-}
-
-void ThemeManager::setApplicationTheme(const QString& name)
-{
- auto systemPalette = qApp->palette();
- auto themeIter = m_themes.find(name);
- if (themeIter != m_themes.end()) {
- auto& theme = themeIter->second;
- themeDebugLog() << "applying theme" << theme->name();
- theme->apply();
- } else {
- themeWarningLog() << "Tried to set invalid theme:" << name;
- }
-}
-
-QString ThemeManager::getCatImage(QString catName)
-{
- QDateTime now = QDateTime::currentDateTime();
- QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
- QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
- QString cat = !catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString();
- if (std::abs(now.daysTo(xmas)) <= 4) {
- cat += "-xmas";
- } else if (std::abs(now.daysTo(halloween)) <= 4) {
- cat += "-spooky";
- } else if (std::abs(now.daysTo(birthday)) <= 12) {
- cat += "-bday";
- }
- return cat;
-}
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#include "ThemeManager.h"
+
+#include
+#include
+#include
+#include
+#include "ui/themes/BrightTheme.h"
+#include "ui/themes/CustomTheme.h"
+#include "ui/themes/DarkTheme.h"
+#include "ui/themes/SystemTheme.h"
+
+#include "Application.h"
+
+ThemeManager::ThemeManager(MainWindow* mainWindow)
+{
+ m_mainWindow = mainWindow;
+ initializeThemes();
+}
+
+/// @brief Adds the Theme to the list of themes
+/// @param theme The Theme to add
+/// @return Theme ID
+QString ThemeManager::addTheme(std::unique_ptr theme)
+{
+ QString id = theme->id();
+ m_themes.emplace(id, std::move(theme));
+ return id;
+}
+
+/// @brief Gets the Theme from the List via ID
+/// @param themeId Theme ID of theme to fetch
+/// @return Theme at themeId
+ITheme* ThemeManager::getTheme(QString themeId)
+{
+ return m_themes[themeId].get();
+}
+
+void ThemeManager::initializeThemes()
+{
+ // Icon themes
+ {
+ // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies!
+ // set icon theme search path!
+ auto searchPaths = QIcon::themeSearchPaths();
+ searchPaths.append("iconthemes");
+ QIcon::setThemeSearchPaths(searchPaths);
+ themeDebugLog() << "<> Icon themes initialized.";
+ }
+
+ // Initialize widget themes
+ {
+ themeDebugLog() << "<> Initializing Widget Themes";
+ themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+ auto darkThemeId = addTheme(std::make_unique());
+ themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
+ themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+
+ // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
+ // dropdown?)
+ QString themeFolder = QDir("./themes/").absoluteFilePath("");
+ themeDebugLog() << "Theme Folder Path: " << themeFolder;
+
+ QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while (directoryIterator.hasNext()) {
+ QDir dir(directoryIterator.next());
+ QFileInfo themeJson(dir.absoluteFilePath("theme.json"));
+ if (themeJson.exists()) {
+ // Load "theme.json" based themes
+ themeDebugLog() << "Loading JSON Theme from:" << themeJson.absoluteFilePath();
+ addTheme(std::make_unique(getTheme(darkThemeId), themeJson, true));
+ } else {
+ // Load pure QSS Themes
+ QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), { "*.qss", "*.css" }, QDir::Files);
+ while (stylesheetFileIterator.hasNext()) {
+ QFile customThemeFile(stylesheetFileIterator.next());
+ QFileInfo customThemeFileInfo(customThemeFile);
+ themeDebugLog() << "Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath();
+ addTheme(std::make_unique(getTheme(darkThemeId), customThemeFileInfo, false));
+ }
+ }
+ }
+
+ themeDebugLog() << "<> Widget themes initialized.";
+ }
+}
+
+QList ThemeManager::getValidApplicationThemes()
+{
+ QList ret;
+ ret.reserve(m_themes.size());
+ for (auto&& [id, theme] : m_themes) {
+ ret.append(theme.get());
+ }
+ return ret;
+}
+
+void ThemeManager::setIconTheme(const QString& name)
+{
+ QIcon::setThemeName(name);
+}
+
+void ThemeManager::applyCurrentlySelectedTheme()
+{
+ setIconTheme(APPLICATION->settings()->get("IconTheme").toString());
+ themeDebugLog() << "<> Icon theme set.";
+ setApplicationTheme(APPLICATION->settings()->get("ApplicationTheme").toString());
+ themeDebugLog() << "<> Application theme set.";
+}
+
+void ThemeManager::setApplicationTheme(const QString& name)
+{
+ auto systemPalette = qApp->palette();
+ auto themeIter = m_themes.find(name);
+ if (themeIter != m_themes.end()) {
+ auto& theme = themeIter->second;
+ themeDebugLog() << "applying theme" << theme->name();
+ theme->apply();
+ } else {
+ themeWarningLog() << "Tried to set invalid theme:" << name;
+ }
+}
+
+QString ThemeManager::getCatImage(QString catName)
+{
+ QDateTime now = QDateTime::currentDateTime();
+ QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
+ QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
+ QDateTime halloween(QDate(now.date().year(), 10, 31), QTime(0, 0));
+ QString cat = !catName.isEmpty() ? catName : APPLICATION->settings()->get("BackgroundCat").toString();
+ if (std::abs(now.daysTo(xmas)) <= 4) {
+ cat += "-xmas";
+ } else if (std::abs(now.daysTo(halloween)) <= 4) {
+ cat += "-spooky";
+ } else if (std::abs(now.daysTo(birthday)) <= 12) {
+ cat += "-bday";
+ }
+ return cat;
+}
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index d5e73bb8..9af44b5a 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -1,57 +1,57 @@
-// SPDX-License-Identifier: GPL-3.0-only
-/*
- * Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
- *
- * 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 .
- */
-#pragma once
-
-#include
-
-#include "ui/MainWindow.h"
-#include "ui/themes/ITheme.h"
-
-inline auto themeDebugLog()
-{
- return qDebug() << "[Theme]";
-}
-inline auto themeWarningLog()
-{
- return qWarning() << "[Theme]";
-}
-
-class ThemeManager {
- public:
- ThemeManager(MainWindow* mainWindow);
-
- QList getValidApplicationThemes();
- void setIconTheme(const QString& name);
- void applyCurrentlySelectedTheme();
- void setApplicationTheme(const QString& name);
-
- ///
- /// Returns the cat based on selected cat and with events (Birthday, XMas, etc.)
- ///
- /// Optional, if you need a specific cat.
- ///
- static QString getCatImage(QString catName = "");
-
- private:
- std::map> m_themes;
- MainWindow* m_mainWindow;
-
- void initializeThemes();
- QString addTheme(std::unique_ptr theme);
- ITheme* getTheme(QString themeId);
-};
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2022 Tayou
+ *
+ * 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 .
+ */
+#pragma once
+
+#include
+
+#include "ui/MainWindow.h"
+#include "ui/themes/ITheme.h"
+
+inline auto themeDebugLog()
+{
+ return qDebug() << "[Theme]";
+}
+inline auto themeWarningLog()
+{
+ return qWarning() << "[Theme]";
+}
+
+class ThemeManager {
+ public:
+ ThemeManager(MainWindow* mainWindow);
+
+ QList getValidApplicationThemes();
+ void setIconTheme(const QString& name);
+ void applyCurrentlySelectedTheme();
+ void setApplicationTheme(const QString& name);
+
+ ///
+ /// Returns the cat based on selected cat and with events (Birthday, XMas, etc.)
+ ///
+ /// Optional, if you need a specific cat.
+ ///
+ static QString getCatImage(QString catName = "");
+
+ private:
+ std::map> m_themes;
+ MainWindow* m_mainWindow;
+
+ void initializeThemes();
+ QString addTheme(std::unique_ptr theme);
+ ITheme* getTheme(QString themeId);
+};
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
index 5fb5bd4e..d0b5be21 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
@@ -1,148 +1,148 @@
-// SPDX-License-Identifier: GPL-3.0-only
-/*
- * Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou