Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into skin_selector
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
commit
2e4fcd6aa3
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -164,7 +164,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Retrieve ccache cache (Windows MinGW-w64)
|
- name: Retrieve ccache cache (Windows MinGW-w64)
|
||||||
if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug'
|
if: runner.os == 'Windows' && matrix.msystem != '' && inputs.build_type == 'Debug'
|
||||||
uses: actions/cache@v3.3.1
|
uses: actions/cache@v3.3.2
|
||||||
with:
|
with:
|
||||||
path: '${{ github.workspace }}\.ccache'
|
path: '${{ github.workspace }}\.ccache'
|
||||||
key: ${{ matrix.os }}-mingw-w64-ccache-${{ github.run_id }}
|
key: ${{ matrix.os }}-mingw-w64-ccache-${{ github.run_id }}
|
||||||
|
28
flake.lock
generated
28
flake.lock
generated
@ -89,13 +89,28 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nix-filter": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1694857738,
|
||||||
|
"narHash": "sha256-bxxNyLHjhu0N8T3REINXQ2ZkJco0ABFPn6PIe2QUfqo=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "nix-filter",
|
||||||
|
"rev": "41fd48e00c22b4ced525af521ead8792402de0ea",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "nix-filter",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693626178,
|
"lastModified": 1695318763,
|
||||||
"narHash": "sha256-Rpiy6lIOu4zny8tfGuIeN1ji9eSz9nPmm9yBhh/4IOM=",
|
"narHash": "sha256-FHVPDRP2AfvsxAdc+AsgFJevMz5VBmnZglFUMlxBkcY=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "bfb7dfec93f3b5d7274db109f2990bc889861caf",
|
"rev": "e12483116b3b51a185a33a272bf351e357ba9a99",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -138,11 +153,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1692274144,
|
"lastModified": 1694364351,
|
||||||
"narHash": "sha256-BxTQuRUANQ81u8DJznQyPmRsg63t4Yc+0kcyq6OLz8s=",
|
"narHash": "sha256-oadhSCqopYXxURwIA6/Anpe5IAG11q2LhvTJNP5zE6o=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "pre-commit-hooks.nix",
|
"repo": "pre-commit-hooks.nix",
|
||||||
"rev": "7e3517c03d46159fdbf8c0e5c97f82d5d4b0c8fa",
|
"rev": "4f883a76282bc28eb952570afc3d8a1bf6f481d7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -156,6 +171,7 @@
|
|||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"libnbtplusplus": "libnbtplusplus",
|
"libnbtplusplus": "libnbtplusplus",
|
||||||
|
"nix-filter": "nix-filter",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"pre-commit-hooks": "pre-commit-hooks"
|
"pre-commit-hooks": "pre-commit-hooks"
|
||||||
}
|
}
|
||||||
|
13
flake.nix
13
flake.nix
@ -4,6 +4,7 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
nix-filter.url = "github:numtide/nix-filter";
|
||||||
pre-commit-hooks = {
|
pre-commit-hooks = {
|
||||||
url = "github:cachix/pre-commit-hooks.nix";
|
url = "github:cachix/pre-commit-hooks.nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@ -20,12 +21,14 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs:
|
outputs = {
|
||||||
inputs.flake-parts.lib.mkFlake
|
flake-parts,
|
||||||
{inherit inputs;}
|
pre-commit-hooks,
|
||||||
{
|
...
|
||||||
|
} @ inputs:
|
||||||
|
flake-parts.lib.mkFlake {inherit inputs;} {
|
||||||
imports = [
|
imports = [
|
||||||
inputs.pre-commit-hooks.flakeModule
|
pre-commit-hooks.flakeModule
|
||||||
|
|
||||||
./nix/dev.nix
|
./nix/dev.nix
|
||||||
./nix/distribution.nix
|
./nix/distribution.nix
|
||||||
|
@ -503,6 +503,9 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
|||||||
|
|
||||||
m_settings->registerSetting("MenuBarInsteadOfToolBar", false);
|
m_settings->registerSetting("MenuBarInsteadOfToolBar", false);
|
||||||
|
|
||||||
|
m_settings->registerSetting("NumberOfConcurrentTasks", 10);
|
||||||
|
m_settings->registerSetting("NumberOfConcurrentDownloads", 6);
|
||||||
|
|
||||||
QString defaultMonospace;
|
QString defaultMonospace;
|
||||||
int defaultSize = 11;
|
int defaultSize = 11;
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
|
@ -1142,6 +1142,9 @@ include(CompilerWarnings)
|
|||||||
|
|
||||||
# Add executable
|
# Add executable
|
||||||
add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${LAUNCHER_SOURCES} ${LAUNCHER_UI} ${LAUNCHER_RESOURCES})
|
add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${LAUNCHER_SOURCES} ${LAUNCHER_UI} ${LAUNCHER_RESOURCES})
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
target_compile_definitions(Launcher_logic PUBLIC LAUNCHER_TEST)
|
||||||
|
endif()
|
||||||
set_project_warnings(Launcher_logic
|
set_project_warnings(Launcher_logic
|
||||||
"${Launcher_MSVC_WARNINGS}"
|
"${Launcher_MSVC_WARNINGS}"
|
||||||
"${Launcher_CLANG_WARNINGS}"
|
"${Launcher_CLANG_WARNINGS}"
|
||||||
|
@ -311,7 +311,7 @@ QString MinecraftInstance::getLocalLibraryPath() const
|
|||||||
bool MinecraftInstance::supportsDemo() const
|
bool MinecraftInstance::supportsDemo() const
|
||||||
{
|
{
|
||||||
Version instance_ver{ getPackProfile()->getComponentVersion("net.minecraft") };
|
Version instance_ver{ getPackProfile()->getComponentVersion("net.minecraft") };
|
||||||
// Demo mode was introduced in 1.3.1: https://minecraft.fandom.com/wiki/Demo_mode#History
|
// Demo mode was introduced in 1.3.1: https://minecraft.wiki/w/Demo_mode#History
|
||||||
// FIXME: Due to Version constraints atm, this can't handle well non-release versions
|
// FIXME: Due to Version constraints atm, this can't handle well non-release versions
|
||||||
return instance_ver >= Version("1.3.1");
|
return instance_ver >= Version("1.3.1");
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
|
|
||||||
// Values taken from:
|
// Values taken from:
|
||||||
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_data_pack#%22pack_format%22
|
// https://minecraft.wiki/w/Tutorials/Creating_a_data_pack#%22pack_format%22
|
||||||
static const QMap<int, std::pair<Version, Version>> s_pack_format_versions = {
|
static const QMap<int, std::pair<Version, Version>> s_pack_format_versions = {
|
||||||
{ 4, { Version("1.13"), Version("1.14.4") } }, { 5, { Version("1.15"), Version("1.16.1") } },
|
{ 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") } },
|
{ 6, { Version("1.16.2"), Version("1.16.5") } }, { 7, { Version("1.17"), Version("1.17.1") } },
|
||||||
|
@ -63,7 +63,7 @@ class DataPack : public Resource {
|
|||||||
mutable QMutex m_data_lock;
|
mutable QMutex m_data_lock;
|
||||||
|
|
||||||
/* The 'version' of a data pack, as defined in the pack.mcmeta file.
|
/* The 'version' of a data pack, as defined in the pack.mcmeta file.
|
||||||
* See https://minecraft.fandom.com/wiki/Data_pack#pack.mcmeta
|
* See https://minecraft.wiki/w/Data_pack#pack.mcmeta
|
||||||
*/
|
*/
|
||||||
int m_pack_format = 0;
|
int m_pack_format = 0;
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObje
|
|||||||
|
|
||||||
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged);
|
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged);
|
||||||
connect(&m_helper_thread_task, &ConcurrentTask::finished, this, [this] { m_helper_thread_task.clear(); });
|
connect(&m_helper_thread_task, &ConcurrentTask::finished, this, [this] { m_helper_thread_task.clear(); });
|
||||||
|
#ifndef LAUNCHER_TEST
|
||||||
|
// in tests the application macro doesn't work
|
||||||
|
m_helper_thread_task.setMaxConcurrent(APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceFolderModel::~ResourceFolderModel()
|
ResourceFolderModel::~ResourceFolderModel()
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
|
#include "minecraft/mod/tasks/LocalResourcePackParseTask.h"
|
||||||
|
|
||||||
// Values taken from:
|
// Values taken from:
|
||||||
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
|
// https://minecraft.wiki/w/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
|
||||||
static const QMap<int, std::pair<Version, Version>> s_pack_format_versions = {
|
static const QMap<int, std::pair<Version, Version>> s_pack_format_versions = {
|
||||||
{ 1, { Version("1.6.1"), Version("1.8.9") } }, { 2, { Version("1.9"), Version("1.10.2") } },
|
{ 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") } },
|
{ 3, { Version("1.11"), Version("1.12.2") } }, { 4, { Version("1.13"), Version("1.14.4") } },
|
||||||
|
@ -51,7 +51,7 @@ class ResourcePack : public Resource {
|
|||||||
mutable QMutex m_data_lock;
|
mutable QMutex m_data_lock;
|
||||||
|
|
||||||
/* The 'version' of a resource pack, as defined in the pack.mcmeta file.
|
/* 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
|
* See https://minecraft.wiki/w/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
|
||||||
*/
|
*/
|
||||||
int m_pack_format = 0;
|
int m_pack_format = 0;
|
||||||
|
|
||||||
|
@ -251,3 +251,32 @@ void GetModDependenciesTask::removePack(const QVariant addonId)
|
|||||||
++it;
|
++it;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHash<QString, QStringList> GetModDependenciesTask::getRequiredBy()
|
||||||
|
{
|
||||||
|
QHash<QString, QStringList> rby;
|
||||||
|
auto fullList = m_selected + m_pack_dependencies;
|
||||||
|
for (auto& mod : fullList) {
|
||||||
|
auto addonId = mod->pack->addonId;
|
||||||
|
auto provider = mod->pack->provider;
|
||||||
|
auto version = mod->version.fileId;
|
||||||
|
auto req = QStringList();
|
||||||
|
for (auto& smod : fullList) {
|
||||||
|
if (provider != smod->pack->provider)
|
||||||
|
continue;
|
||||||
|
auto deps = smod->version.dependencies;
|
||||||
|
if (auto dep = std::find_if(deps.begin(), deps.end(),
|
||||||
|
[addonId, provider, version](const ModPlatform::Dependency& d) {
|
||||||
|
return d.type == ModPlatform::DependencyType::REQUIRED &&
|
||||||
|
(provider == ModPlatform::ResourceProvider::MODRINTH && d.addonId.toString().isEmpty()
|
||||||
|
? version == d.version
|
||||||
|
: d.addonId == addonId);
|
||||||
|
});
|
||||||
|
dep != deps.end()) {
|
||||||
|
req.append(smod->pack->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rby[addonId.toString()] = req;
|
||||||
|
}
|
||||||
|
return rby;
|
||||||
|
}
|
@ -62,6 +62,7 @@ class GetModDependenciesTask : public SequentialTask {
|
|||||||
QList<std::shared_ptr<PackDependency>> selected);
|
QList<std::shared_ptr<PackDependency>> selected);
|
||||||
|
|
||||||
auto getDependecies() const -> QList<std::shared_ptr<PackDependency>> { return m_pack_dependencies; }
|
auto getDependecies() const -> QList<std::shared_ptr<PackDependency>> { return m_pack_dependencies; }
|
||||||
|
QHash<QString, QStringList> getRequiredBy();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int);
|
Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int);
|
||||||
|
@ -133,7 +133,7 @@ bool processZIP(DataPack& pack, ProcessingLevel level)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://minecraft.fandom.com/wiki/Data_pack#pack.mcmeta
|
// https://minecraft.wiki/w/Data_pack#pack.mcmeta
|
||||||
bool processMCMeta(DataPack& pack, QByteArray&& raw_data)
|
bool processMCMeta(DataPack& pack, QByteArray&& raw_data)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -178,7 +178,7 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://minecraft.fandom.com/wiki/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
|
// https://minecraft.wiki/w/Tutorials/Creating_a_resource_pack#Formatting_pack.mcmeta
|
||||||
bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data)
|
bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "minecraft/mod/Mod.h"
|
#include "minecraft/mod/Mod.h"
|
||||||
|
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
#include "modplatform/ResourceAPI.h"
|
#include "modplatform/ResourceAPI.h"
|
||||||
#include "tasks/Task.h"
|
#include "tasks/Task.h"
|
||||||
@ -40,6 +41,7 @@ class CheckUpdateTask : public Task {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto getUpdatable() -> std::vector<UpdatableMod>&& { return std::move(m_updatable); }
|
auto getUpdatable() -> std::vector<UpdatableMod>&& { return std::move(m_updatable); }
|
||||||
|
auto getDependencies() -> QList<std::shared_ptr<GetModDependenciesTask::PackDependency>>&& { return std::move(m_deps); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool abort() override = 0;
|
bool abort() override = 0;
|
||||||
@ -57,4 +59,5 @@ class CheckUpdateTask : public Task {
|
|||||||
std::shared_ptr<ModFolderModel> m_mods_folder;
|
std::shared_ptr<ModFolderModel> m_mods_folder;
|
||||||
|
|
||||||
std::vector<UpdatableMod> m_updatable;
|
std::vector<UpdatableMod> m_updatable;
|
||||||
|
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> m_deps;
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <MurmurHash2.h>
|
#include <MurmurHash2.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
|
|
||||||
#include "minecraft/mod/Mod.h"
|
#include "minecraft/mod/Mod.h"
|
||||||
@ -33,7 +34,7 @@ EnsureMetadataTask::EnsureMetadataTask(Mod* mod, QDir dir, ModPlatform::Resource
|
|||||||
EnsureMetadataTask::EnsureMetadataTask(QList<Mod*>& mods, QDir dir, ModPlatform::ResourceProvider prov)
|
EnsureMetadataTask::EnsureMetadataTask(QList<Mod*>& mods, QDir dir, ModPlatform::ResourceProvider prov)
|
||||||
: Task(nullptr), m_index_dir(dir), m_provider(prov), m_current_task(nullptr)
|
: Task(nullptr), m_index_dir(dir), m_provider(prov), m_current_task(nullptr)
|
||||||
{
|
{
|
||||||
m_hashing_task.reset(new ConcurrentTask(this, "MakeHashesTask", 10));
|
m_hashing_task.reset(new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
|
||||||
for (auto* mod : mods) {
|
for (auto* mod : mods) {
|
||||||
auto hash_task = createNewHash(mod);
|
auto hash_task = createNewHash(mod);
|
||||||
if (!hash_task)
|
if (!hash_task)
|
||||||
|
@ -38,6 +38,8 @@ class FlameAPI : public NetworkResourceAPI {
|
|||||||
return 6;
|
return 6;
|
||||||
case ModPlatform::ResourceType::RESOURCE_PACK:
|
case ModPlatform::ResourceType::RESOURCE_PACK:
|
||||||
return 12;
|
return 12;
|
||||||
|
case ModPlatform::ResourceType::SHADER_PACK:
|
||||||
|
return 6552;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "ResourceDownloadTask.h"
|
#include "ResourceDownloadTask.h"
|
||||||
|
|
||||||
#include "minecraft/mod/ModFolderModel.h"
|
#include "minecraft/mod/ModFolderModel.h"
|
||||||
|
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
|
||||||
|
|
||||||
#include "net/ApiDownload.h"
|
#include "net/ApiDownload.h"
|
||||||
|
|
||||||
@ -154,7 +155,6 @@ void FlameCheckUpdate::executeTask()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
|
|
||||||
// Fake pack with the necessary info to pass to the download task :)
|
// Fake pack with the necessary info to pass to the download task :)
|
||||||
auto pack = std::make_shared<ModPlatform::IndexedPack>();
|
auto pack = std::make_shared<ModPlatform::IndexedPack>();
|
||||||
pack->name = mod->name();
|
pack->name = mod->name();
|
||||||
@ -165,7 +165,7 @@ void FlameCheckUpdate::executeTask()
|
|||||||
pack->authors.append({ author });
|
pack->authors.append({ author });
|
||||||
pack->description = mod->description();
|
pack->description = mod->description();
|
||||||
pack->provider = ModPlatform::ResourceProvider::FLAME;
|
pack->provider = ModPlatform::ResourceProvider::FLAME;
|
||||||
|
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
|
||||||
auto old_version = mod->version();
|
auto old_version = mod->version();
|
||||||
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
|
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
|
||||||
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
|
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
|
||||||
@ -177,6 +177,7 @@ void FlameCheckUpdate::executeTask()
|
|||||||
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
|
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
|
||||||
ModPlatform::ResourceProvider::FLAME, download_task);
|
ModPlatform::ResourceProvider::FLAME, download_task);
|
||||||
}
|
}
|
||||||
|
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver));
|
||||||
}
|
}
|
||||||
|
|
||||||
emitSucceeded();
|
emitSucceeded();
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "Application.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "MMCZip.h"
|
#include "MMCZip.h"
|
||||||
#include "minecraft/PackProfile.h"
|
#include "minecraft/PackProfile.h"
|
||||||
@ -102,7 +103,8 @@ void FlamePackExportTask::collectHashes()
|
|||||||
setStatus(tr("Finding file hashes..."));
|
setStatus(tr("Finding file hashes..."));
|
||||||
setProgress(1, 5);
|
setProgress(1, 5);
|
||||||
auto allMods = mcInstance->loaderModList()->allMods();
|
auto allMods = mcInstance->loaderModList()->allMods();
|
||||||
ConcurrentTask::Ptr hashingTask(new ConcurrentTask(this, "MakeHashesTask", 10));
|
ConcurrentTask::Ptr hashingTask(
|
||||||
|
new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
|
||||||
task.reset(hashingTask);
|
task.reset(hashingTask);
|
||||||
for (const QFileInfo& file : files) {
|
for (const QFileInfo& file : files) {
|
||||||
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());
|
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());
|
||||||
|
@ -38,7 +38,7 @@ void ModrinthCheckUpdate::executeTask()
|
|||||||
QStringList hashes;
|
QStringList hashes;
|
||||||
auto best_hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first();
|
auto best_hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first();
|
||||||
|
|
||||||
ConcurrentTask hashing_task(this, "MakeModrinthHashesTask", 10);
|
ConcurrentTask hashing_task(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
|
||||||
for (auto* mod : m_mods) {
|
for (auto* mod : m_mods) {
|
||||||
if (!mod->enabled()) {
|
if (!mod->enabled()) {
|
||||||
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
||||||
@ -144,9 +144,6 @@ void ModrinthCheckUpdate::executeTask()
|
|||||||
auto mod = *mod_iter;
|
auto mod = *mod_iter;
|
||||||
|
|
||||||
auto key = project_ver.hash;
|
auto key = project_ver.hash;
|
||||||
if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
|
|
||||||
if (mod->version() == project_ver.version_number)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Fake pack with the necessary info to pass to the download task :)
|
// Fake pack with the necessary info to pass to the download task :)
|
||||||
auto pack = std::make_shared<ModPlatform::IndexedPack>();
|
auto pack = std::make_shared<ModPlatform::IndexedPack>();
|
||||||
@ -158,12 +155,16 @@ void ModrinthCheckUpdate::executeTask()
|
|||||||
pack->authors.append({ author });
|
pack->authors.append({ author });
|
||||||
pack->description = mod->description();
|
pack->description = mod->description();
|
||||||
pack->provider = ModPlatform::ResourceProvider::MODRINTH;
|
pack->provider = ModPlatform::ResourceProvider::MODRINTH;
|
||||||
|
if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
|
||||||
|
if (mod->version() == project_ver.version_number)
|
||||||
|
continue;
|
||||||
|
|
||||||
auto download_task = makeShared<ResourceDownloadTask>(pack, project_ver, m_mods_folder);
|
auto download_task = makeShared<ResourceDownloadTask>(pack, project_ver, m_mods_folder);
|
||||||
|
|
||||||
m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.changelog,
|
m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.changelog,
|
||||||
ModPlatform::ResourceProvider::MODRINTH, download_task);
|
ModPlatform::ResourceProvider::MODRINTH, download_task);
|
||||||
}
|
}
|
||||||
|
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, project_ver));
|
||||||
}
|
}
|
||||||
} catch (Json::JsonException& e) {
|
} catch (Json::JsonException& e) {
|
||||||
failed(e.cause() + " : " + e.what());
|
failed(e.cause() + " : " + e.what());
|
||||||
|
@ -36,6 +36,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "NetJob.h"
|
#include "NetJob.h"
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
|
NetJob::NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network, int max_concurrent)
|
||||||
|
: ConcurrentTask(nullptr,
|
||||||
|
job_name,
|
||||||
|
max_concurrent < 0 ? APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt() : max_concurrent)
|
||||||
|
, m_network(network)
|
||||||
|
{}
|
||||||
|
|
||||||
auto NetJob::addNetAction(NetAction::Ptr action) -> bool
|
auto NetJob::addNetAction(NetAction::Ptr action) -> bool
|
||||||
{
|
{
|
||||||
|
@ -52,9 +52,7 @@ class NetJob : public ConcurrentTask {
|
|||||||
public:
|
public:
|
||||||
using Ptr = shared_qobject_ptr<NetJob>;
|
using Ptr = shared_qobject_ptr<NetJob>;
|
||||||
|
|
||||||
explicit NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network, int max_concurrent = 6)
|
explicit NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network, int max_concurrent = -1);
|
||||||
: ConcurrentTask(nullptr, job_name, max_concurrent), m_network(network)
|
|
||||||
{}
|
|
||||||
~NetJob() override = default;
|
~NetJob() override = default;
|
||||||
|
|
||||||
void startNext() override;
|
void startNext() override;
|
||||||
|
@ -51,6 +51,9 @@ class ConcurrentTask : public Task {
|
|||||||
explicit ConcurrentTask(QObject* parent = nullptr, QString task_name = "", int max_concurrent = 6);
|
explicit ConcurrentTask(QObject* parent = nullptr, QString task_name = "", int max_concurrent = 6);
|
||||||
~ConcurrentTask() override;
|
~ConcurrentTask() override;
|
||||||
|
|
||||||
|
// safe to call before starting the task
|
||||||
|
void setMaxConcurrent(int max_concurrent) { m_total_max_size = max_concurrent; }
|
||||||
|
|
||||||
bool canAbort() const override { return true; }
|
bool canAbort() const override { return true; }
|
||||||
|
|
||||||
inline auto isMultiStep() const -> bool override { return totalSize() > 1; }
|
inline auto isMultiStep() const -> bool override { return totalSize() > 1; }
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods)
|
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods)
|
||||||
: QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)
|
: QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)
|
||||||
{
|
{
|
||||||
m_hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10));
|
m_hashing_task = shared_qobject_ptr<ConcurrentTask>(
|
||||||
|
new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
|
||||||
connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
|
connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include "CustomMessageBox.h"
|
#include "CustomMessageBox.h"
|
||||||
#include "ProgressDialog.h"
|
#include "ProgressDialog.h"
|
||||||
#include "ScrollMessageBox.h"
|
#include "ScrollMessageBox.h"
|
||||||
|
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
|
#include "modplatform/flame/FlameAPI.h"
|
||||||
#include "ui_ReviewMessageBox.h"
|
#include "ui_ReviewMessageBox.h"
|
||||||
|
|
||||||
#include "Markdown.h"
|
#include "Markdown.h"
|
||||||
@ -41,7 +44,8 @@ ModUpdateDialog::ModUpdateDialog(QWidget* parent,
|
|||||||
, m_parent(parent)
|
, m_parent(parent)
|
||||||
, m_mod_model(mods)
|
, m_mod_model(mods)
|
||||||
, m_candidates(search_for)
|
, m_candidates(search_for)
|
||||||
, m_second_try_metadata(new ConcurrentTask())
|
, m_second_try_metadata(
|
||||||
|
new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))
|
||||||
, m_instance(instance)
|
, m_instance(instance)
|
||||||
{
|
{
|
||||||
ReviewMessageBox::setGeometry(0, 0, 800, 600);
|
ReviewMessageBox::setGeometry(0, 0, 800, 600);
|
||||||
@ -124,6 +128,8 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
|
||||||
|
|
||||||
// Add found updates for Modrinth
|
// Add found updates for Modrinth
|
||||||
if (m_modrinth_check_task) {
|
if (m_modrinth_check_task) {
|
||||||
auto modrinth_updates = m_modrinth_check_task->getUpdatable();
|
auto modrinth_updates = m_modrinth_check_task->getUpdatable();
|
||||||
@ -133,6 +139,7 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
appendMod(updatable);
|
appendMod(updatable);
|
||||||
m_tasks.insert(updatable.name, updatable.download);
|
m_tasks.insert(updatable.name, updatable.download);
|
||||||
}
|
}
|
||||||
|
selectedVers.append(m_modrinth_check_task->getDependencies());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add found updated for Flame
|
// Add found updated for Flame
|
||||||
@ -144,6 +151,7 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
appendMod(updatable);
|
appendMod(updatable);
|
||||||
m_tasks.insert(updatable.name, updatable.download);
|
m_tasks.insert(updatable.name, updatable.download);
|
||||||
}
|
}
|
||||||
|
selectedVers.append(m_flame_check_task->getDependencies());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report failed update checking
|
// Report failed update checking
|
||||||
@ -178,6 +186,47 @@ void ModUpdateDialog::checkCandidates()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // dependencies
|
||||||
|
auto depTask = makeShared<GetModDependenciesTask>(this, m_instance, m_mod_model.get(), selectedVers);
|
||||||
|
|
||||||
|
connect(depTask.get(), &Task::failed, this,
|
||||||
|
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
|
||||||
|
|
||||||
|
connect(depTask.get(), &Task::succeeded, this, [&]() {
|
||||||
|
QStringList warnings = depTask->warnings();
|
||||||
|
if (warnings.count()) {
|
||||||
|
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ProgressDialog progress_dialog_deps(m_parent);
|
||||||
|
progress_dialog_deps.setSkipButton(true, tr("Abort"));
|
||||||
|
progress_dialog_deps.setWindowTitle(tr("Checking for dependencies..."));
|
||||||
|
auto dret = progress_dialog_deps.execWithTask(depTask.get());
|
||||||
|
|
||||||
|
// If the dialog was skipped / some download error happened
|
||||||
|
if (dret == QDialog::DialogCode::Rejected) {
|
||||||
|
m_aborted = true;
|
||||||
|
QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static FlameAPI api;
|
||||||
|
|
||||||
|
auto getRequiredBy = depTask->getRequiredBy();
|
||||||
|
|
||||||
|
for (auto dep : depTask->getDependecies()) {
|
||||||
|
auto changelog = dep->version.changelog;
|
||||||
|
if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME)
|
||||||
|
changelog = api.getModFileChangelog(dep->version.addonId.toInt(), dep->version.fileId.toInt());
|
||||||
|
auto download_task = makeShared<ResourceDownloadTask>(dep->pack, dep->version, m_mod_model);
|
||||||
|
CheckUpdateTask::UpdatableMod updatable = { dep->pack->name, dep->version.hash, "", dep->version.version,
|
||||||
|
changelog, dep->pack->provider, download_task };
|
||||||
|
|
||||||
|
appendMod(updatable, getRequiredBy.value(dep->version.addonId.toString()));
|
||||||
|
m_tasks.insert(updatable.name, updatable.download);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there's no mod to be updated
|
// If there's no mod to be updated
|
||||||
if (ui->modTreeWidget->topLevelItemCount() == 0) {
|
if (ui->modTreeWidget->topLevelItemCount() == 0) {
|
||||||
m_no_updates = true;
|
m_no_updates = true;
|
||||||
@ -236,6 +285,10 @@ auto ModUpdateDialog::ensureMetadata() -> bool
|
|||||||
if (skip_rest)
|
if (skip_rest)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (candidate->type() == ResourceType::FOLDER) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (confirm_rest) {
|
if (confirm_rest) {
|
||||||
addToTmp(candidate, provider_rest);
|
addToTmp(candidate, provider_rest);
|
||||||
should_try_others.insert(candidate->internal_id(), try_others_rest);
|
should_try_others.insert(candidate->internal_id(), try_others_rest);
|
||||||
@ -346,7 +399,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
|
void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info, QStringList requiredBy)
|
||||||
{
|
{
|
||||||
auto item_top = new QTreeWidgetItem(ui->modTreeWidget);
|
auto item_top = new QTreeWidgetItem(ui->modTreeWidget);
|
||||||
item_top->setCheckState(0, Qt::CheckState::Checked);
|
item_top->setCheckState(0, Qt::CheckState::Checked);
|
||||||
@ -362,6 +415,21 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
|
|||||||
auto new_version_item = new QTreeWidgetItem(item_top);
|
auto new_version_item = new QTreeWidgetItem(item_top);
|
||||||
new_version_item->setText(0, tr("New version: %1").arg(info.new_version));
|
new_version_item->setText(0, tr("New version: %1").arg(info.new_version));
|
||||||
|
|
||||||
|
if (!requiredBy.isEmpty()) {
|
||||||
|
auto requiredByItem = new QTreeWidgetItem(item_top);
|
||||||
|
if (requiredBy.length() == 1) {
|
||||||
|
requiredByItem->setText(0, tr("Required by: %1").arg(requiredBy.back()));
|
||||||
|
} else {
|
||||||
|
requiredByItem->setText(0, tr("Required by:"));
|
||||||
|
auto i = 0;
|
||||||
|
for (auto req : requiredBy) {
|
||||||
|
auto reqItem = new QTreeWidgetItem(requiredByItem);
|
||||||
|
reqItem->setText(0, req);
|
||||||
|
reqItem->insertChildren(i++, { reqItem });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto changelog_item = new QTreeWidgetItem(item_top);
|
auto changelog_item = new QTreeWidgetItem(item_top);
|
||||||
changelog_item->setText(0, tr("Changelog of the latest version"));
|
changelog_item->setText(0, tr("Changelog of the latest version"));
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class ModUpdateDialog final : public ReviewMessageBox {
|
|||||||
|
|
||||||
void checkCandidates();
|
void checkCandidates();
|
||||||
|
|
||||||
void appendMod(const CheckUpdateTask::UpdatableMod& info);
|
void appendMod(const CheckUpdateTask::UpdatableMod& info, QStringList requiredBy = {});
|
||||||
|
|
||||||
const QList<ResourceDownloadTask::Ptr> getTasks();
|
const QList<ResourceDownloadTask::Ptr> getTasks();
|
||||||
auto indexDir() const -> QDir { return m_mod_model->indexDir(); }
|
auto indexDir() const -> QDir { return m_mod_model->indexDir(); }
|
||||||
|
@ -127,35 +127,12 @@ void ResourceDownloadDialog::connectButtons()
|
|||||||
|
|
||||||
static ModPlatform::ProviderCapabilities ProviderCaps;
|
static ModPlatform::ProviderCapabilities ProviderCaps;
|
||||||
|
|
||||||
QStringList getRequiredBy(QList<ResourceDownloadDialog::DownloadTaskPtr> tasks, ResourceDownloadDialog::DownloadTaskPtr pack)
|
|
||||||
{
|
|
||||||
auto addonId = pack->getPack()->addonId;
|
|
||||||
auto provider = pack->getPack()->provider;
|
|
||||||
auto version = pack->getVersionID();
|
|
||||||
auto req = QStringList();
|
|
||||||
for (auto& task : tasks) {
|
|
||||||
if (provider != task->getPack()->provider)
|
|
||||||
continue;
|
|
||||||
auto deps = task->getVersion().dependencies;
|
|
||||||
if (auto dep = std::find_if(deps.begin(), deps.end(),
|
|
||||||
[addonId, provider, version](const ModPlatform::Dependency& d) {
|
|
||||||
return d.type == ModPlatform::DependencyType::REQUIRED &&
|
|
||||||
(provider == ModPlatform::ResourceProvider::MODRINTH && d.addonId.toString().isEmpty()
|
|
||||||
? version == d.version
|
|
||||||
: d.addonId == addonId);
|
|
||||||
});
|
|
||||||
dep != deps.end()) {
|
|
||||||
req.append(task->getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceDownloadDialog::confirm()
|
void ResourceDownloadDialog::confirm()
|
||||||
{
|
{
|
||||||
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
|
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
|
||||||
confirm_dialog->retranslateUi(resourcesString());
|
confirm_dialog->retranslateUi(resourcesString());
|
||||||
|
|
||||||
|
QHash<QString, QStringList> getRequiredBy;
|
||||||
if (auto task = getModDependenciesTask(); task) {
|
if (auto task = getModDependenciesTask(); task) {
|
||||||
connect(task.get(), &Task::failed, this,
|
connect(task.get(), &Task::failed, this,
|
||||||
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
|
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
|
||||||
@ -180,6 +157,7 @@ void ResourceDownloadDialog::confirm()
|
|||||||
} else {
|
} else {
|
||||||
for (auto dep : task->getDependecies())
|
for (auto dep : task->getDependecies())
|
||||||
addResource(dep->pack, dep->version);
|
addResource(dep->pack, dep->version);
|
||||||
|
getRequiredBy = task->getRequiredBy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +167,8 @@ void ResourceDownloadDialog::confirm()
|
|||||||
});
|
});
|
||||||
for (auto& task : selected) {
|
for (auto& task : selected) {
|
||||||
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(),
|
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(),
|
||||||
ProviderCaps.name(task->getProvider()), getRequiredBy(selected, task) });
|
ProviderCaps.name(task->getProvider()),
|
||||||
|
getRequiredBy.value(task->getPack()->addonId.toString()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (confirm_dialog->exec()) {
|
if (confirm_dialog->exec()) {
|
||||||
@ -370,6 +349,8 @@ QList<BasePage*> ShaderPackDownloadDialog::getPages()
|
|||||||
{
|
{
|
||||||
QList<BasePage*> pages;
|
QList<BasePage*> pages;
|
||||||
pages.append(ModrinthShaderPackPage::create(this, *m_instance));
|
pages.append(ModrinthShaderPackPage::create(this, *m_instance));
|
||||||
|
if (APPLICATION->capabilities() & Application::SupportsFlame)
|
||||||
|
pages.append(FlameShaderPackPage::create(this, *m_instance));
|
||||||
return pages;
|
return pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +200,9 @@ void LauncherPage::applySettings()
|
|||||||
|
|
||||||
s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked());
|
s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked());
|
||||||
|
|
||||||
|
s->set("NumberOfConcurrentTasks", ui->numberOfConcurrentTasksSpinBox->value());
|
||||||
|
s->set("NumberOfConcurrentDownloads", ui->numberOfConcurrentDownloadsSpinBox->value());
|
||||||
|
|
||||||
// Console settings
|
// Console settings
|
||||||
s->set("ShowConsole", ui->showConsoleCheck->isChecked());
|
s->set("ShowConsole", ui->showConsoleCheck->isChecked());
|
||||||
s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
|
s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
|
||||||
@ -248,6 +251,9 @@ void LauncherPage::loadSettings()
|
|||||||
#endif
|
#endif
|
||||||
ui->preferMenuBarCheckBox->setChecked(s->get("MenuBarInsteadOfToolBar").toBool());
|
ui->preferMenuBarCheckBox->setChecked(s->get("MenuBarInsteadOfToolBar").toBool());
|
||||||
|
|
||||||
|
ui->numberOfConcurrentTasksSpinBox->setValue(s->get("NumberOfConcurrentTasks").toInt());
|
||||||
|
ui->numberOfConcurrentDownloadsSpinBox->setValue(s->get("NumberOfConcurrentDownloads").toInt());
|
||||||
|
|
||||||
// Console settings
|
// Console settings
|
||||||
ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());
|
ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());
|
||||||
ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool());
|
ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool());
|
||||||
|
@ -209,6 +209,43 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="miscellaneousGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Miscellaneous</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="numberOfConcurrentTasksLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Number of concurrent tasks</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="numberOfConcurrentTasksSpinBox">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="numberOfConcurrentDownloadsLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Number of concurrent downloads</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="numberOfConcurrentDownloadsSpinBox">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -175,7 +175,7 @@ void ModFolderPage::installMods()
|
|||||||
|
|
||||||
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
|
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
|
||||||
if (mdownload.exec()) {
|
if (mdownload.exec()) {
|
||||||
ConcurrentTask* tasks = new ConcurrentTask(this);
|
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||||
tasks->deleteLater();
|
tasks->deleteLater();
|
||||||
@ -234,7 +234,7 @@ void ModFolderPage::updateMods()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update_dialog.exec()) {
|
if (update_dialog.exec()) {
|
||||||
ConcurrentTask* tasks = new ConcurrentTask(this);
|
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||||
tasks->deleteLater();
|
tasks->deleteLater();
|
||||||
|
@ -72,7 +72,8 @@ void ResourcePackPage::downloadRPs()
|
|||||||
|
|
||||||
ResourceDownload::ResourcePackDownloadDialog mdownload(this, std::static_pointer_cast<ResourcePackFolderModel>(m_model), m_instance);
|
ResourceDownload::ResourcePackDownloadDialog mdownload(this, std::static_pointer_cast<ResourcePackFolderModel>(m_model), m_instance);
|
||||||
if (mdownload.exec()) {
|
if (mdownload.exec()) {
|
||||||
auto tasks = new ConcurrentTask(this);
|
auto tasks =
|
||||||
|
new ConcurrentTask(this, "Download Resource Pack", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||||
tasks->deleteLater();
|
tasks->deleteLater();
|
||||||
|
@ -65,7 +65,7 @@ void ShaderPackPage::downloadShaders()
|
|||||||
|
|
||||||
ResourceDownload::ShaderPackDownloadDialog mdownload(this, std::static_pointer_cast<ShaderPackFolderModel>(m_model), m_instance);
|
ResourceDownload::ShaderPackDownloadDialog mdownload(this, std::static_pointer_cast<ShaderPackFolderModel>(m_model), m_instance);
|
||||||
if (mdownload.exec()) {
|
if (mdownload.exec()) {
|
||||||
auto tasks = new ConcurrentTask(this);
|
auto tasks = new ConcurrentTask(this, "Download Shaders", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||||
tasks->deleteLater();
|
tasks->deleteLater();
|
||||||
|
@ -74,7 +74,8 @@ void TexturePackPage::downloadTPs()
|
|||||||
|
|
||||||
ResourceDownload::TexturePackDownloadDialog mdownload(this, std::static_pointer_cast<TexturePackFolderModel>(m_model), m_instance);
|
ResourceDownload::TexturePackDownloadDialog mdownload(this, std::static_pointer_cast<TexturePackFolderModel>(m_model), m_instance);
|
||||||
if (mdownload.exec()) {
|
if (mdownload.exec()) {
|
||||||
auto tasks = new ConcurrentTask(this);
|
auto tasks =
|
||||||
|
new ConcurrentTask(this, "Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||||
tasks->deleteLater();
|
tasks->deleteLater();
|
||||||
|
@ -31,6 +31,9 @@ QHash<ResourceModel*, bool> ResourceModel::s_running_models;
|
|||||||
ResourceModel::ResourceModel(ResourceAPI* api) : QAbstractListModel(), m_api(api)
|
ResourceModel::ResourceModel(ResourceAPI* api) : QAbstractListModel(), m_api(api)
|
||||||
{
|
{
|
||||||
s_running_models.insert(this, true);
|
s_running_models.insert(this, true);
|
||||||
|
#ifndef LAUNCHER_TEST
|
||||||
|
m_current_info_job.setMaxConcurrent(APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceModel::~ResourceModel()
|
ResourceModel::~ResourceModel()
|
||||||
|
@ -121,4 +121,27 @@ auto FlameTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonAr
|
|||||||
return Json::ensureArray(obj.object(), "data");
|
return Json::ensureArray(obj.object(), "data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlameShaderPackModel::FlameShaderPackModel(const BaseInstance& base) : ShaderPackResourceModel(base, new FlameAPI) {}
|
||||||
|
|
||||||
|
void FlameShaderPackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||||
|
{
|
||||||
|
FlameMod::loadIndexedPack(m, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We already deal with the URLs when initializing the pack, due to the API response's structure
|
||||||
|
void FlameShaderPackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||||
|
{
|
||||||
|
FlameMod::loadBody(m, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlameShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
||||||
|
{
|
||||||
|
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto FlameShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||||
|
{
|
||||||
|
return Json::ensureArray(obj.object(), "data");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -68,4 +68,21 @@ class FlameTexturePackModel : public TexturePackResourceModel {
|
|||||||
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FlameShaderPackModel : public ShaderPackResourceModel {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlameShaderPackModel(const BaseInstance&);
|
||||||
|
~FlameShaderPackModel() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
[[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; }
|
||||||
|
[[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); }
|
||||||
|
|
||||||
|
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||||
|
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||||
|
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
||||||
|
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -173,6 +173,45 @@ void FlameTexturePackPage::openUrl(const QUrl& url)
|
|||||||
TexturePackResourcePage::openUrl(url);
|
TexturePackResourcePage::openUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlameShaderPackPage::FlameShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||||
|
: ShaderPackResourcePage(dialog, instance)
|
||||||
|
{
|
||||||
|
m_model = new FlameShaderPackModel(instance);
|
||||||
|
m_ui->packView->setModel(m_model);
|
||||||
|
|
||||||
|
addSortings();
|
||||||
|
|
||||||
|
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||||
|
// so it's best not to connect them in the parent's constructor...
|
||||||
|
connect(m_ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
|
||||||
|
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameShaderPackPage::onSelectionChanged);
|
||||||
|
connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlameShaderPackPage::onVersionSelectionChanged);
|
||||||
|
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameShaderPackPage::onResourceSelected);
|
||||||
|
|
||||||
|
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FlameShaderPackPage::optedOut(ModPlatform::IndexedVersion& ver) const
|
||||||
|
{
|
||||||
|
return isOptedOut(ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlameShaderPackPage::openUrl(const QUrl& url)
|
||||||
|
{
|
||||||
|
if (url.scheme().isEmpty()) {
|
||||||
|
QString query = url.query(QUrl::FullyDecoded);
|
||||||
|
|
||||||
|
if (query.startsWith("remoteUrl=")) {
|
||||||
|
// attempt to resolve url from warning page
|
||||||
|
query.remove(0, 10);
|
||||||
|
ShaderPackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderPackResourcePage::openUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
// I don't know why, but doing this on the parent class makes it so that
|
// I don't know why, but doing this on the parent class makes it so that
|
||||||
// other mod providers start loading before being selected, at least with
|
// other mod providers start loading before being selected, at least with
|
||||||
// my Qt, so we need to implement this in every derived class...
|
// my Qt, so we need to implement this in every derived class...
|
||||||
@ -188,5 +227,9 @@ auto FlameTexturePackPage::shouldDisplay() const -> bool
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
auto FlameShaderPackPage::shouldDisplay() const -> bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include "ui/pages/modplatform/ModPage.h"
|
#include "ui/pages/modplatform/ModPage.h"
|
||||||
#include "ui/pages/modplatform/ResourcePackPage.h"
|
#include "ui/pages/modplatform/ResourcePackPage.h"
|
||||||
|
#include "ui/pages/modplatform/ShaderPackPage.h"
|
||||||
#include "ui/pages/modplatform/TexturePackPage.h"
|
#include "ui/pages/modplatform/TexturePackPage.h"
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
@ -155,4 +156,31 @@ class FlameTexturePackPage : public TexturePackResourcePage {
|
|||||||
void openUrl(const QUrl& url) override;
|
void openUrl(const QUrl& url) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FlameShaderPackPage : public ShaderPackResourcePage {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static FlameShaderPackPage* create(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||||
|
{
|
||||||
|
return ShaderPackResourcePage::create<FlameShaderPackPage>(dialog, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlameShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
|
||||||
|
~FlameShaderPackPage() override = default;
|
||||||
|
|
||||||
|
[[nodiscard]] bool shouldDisplay() const override;
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||||
|
[[nodiscard]] inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||||
|
[[nodiscard]] inline auto id() const -> QString override { return Flame::id(); }
|
||||||
|
[[nodiscard]] inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||||
|
[[nodiscard]] inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto helpPage() const -> QString override { return ""; }
|
||||||
|
|
||||||
|
bool optedOut(ModPlatform::IndexedVersion& ver) const override;
|
||||||
|
|
||||||
|
void openUrl(const QUrl& url) override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -99,18 +99,22 @@ QDate ensureDay(int year, int month, int day)
|
|||||||
|
|
||||||
QString JsonCatPack::path()
|
QString JsonCatPack::path()
|
||||||
{
|
{
|
||||||
const QDate now = QDate::currentDate();
|
return path(QDate::currentDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString JsonCatPack::path(QDate now)
|
||||||
|
{
|
||||||
for (auto var : m_variants) {
|
for (auto var : m_variants) {
|
||||||
QDate startDate = ensureDay(now.year(), var.startTime.month, var.startTime.day);
|
QDate startDate = ensureDay(now.year(), var.startTime.month, var.startTime.day);
|
||||||
QDate endDate = ensureDay(now.year(), var.endTime.month, var.endTime.day);
|
QDate endDate = ensureDay(now.year(), var.endTime.month, var.endTime.day);
|
||||||
if (startDate > endDate) { // it's spans over multiple years
|
if (startDate > endDate) { // it's spans over multiple years
|
||||||
if (endDate <= now) // end date is in the past so jump one year into the future for endDate
|
if (endDate < now) // end date is in the past so jump one year into the future for endDate
|
||||||
endDate = endDate.addYears(1);
|
endDate = endDate.addYears(1);
|
||||||
else // end date is in the future so jump one year into the past for startDate
|
else // end date is in the future so jump one year into the past for startDate
|
||||||
startDate = startDate.addYears(-1);
|
startDate = startDate.addYears(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startDate >= now && now >= endDate)
|
if (startDate <= now && now <= endDate)
|
||||||
return var.path;
|
return var.path;
|
||||||
}
|
}
|
||||||
return m_defaultPath;
|
return m_defaultPath;
|
||||||
|
@ -52,9 +52,9 @@ class BasicCatPack : public CatPack {
|
|||||||
public:
|
public:
|
||||||
BasicCatPack(QString id, QString name) : m_id(id), m_name(name) {}
|
BasicCatPack(QString id, QString name) : m_id(id), m_name(name) {}
|
||||||
BasicCatPack(QString id) : BasicCatPack(id, id) {}
|
BasicCatPack(QString id) : BasicCatPack(id, id) {}
|
||||||
virtual QString id() { return m_id; }
|
virtual QString id() override { return m_id; }
|
||||||
virtual QString name() { return m_name; }
|
virtual QString name() override { return m_name; }
|
||||||
virtual QString path();
|
virtual QString path() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_id;
|
QString m_id;
|
||||||
@ -83,7 +83,8 @@ class JsonCatPack : public BasicCatPack {
|
|||||||
PartialDate endTime;
|
PartialDate endTime;
|
||||||
};
|
};
|
||||||
JsonCatPack(QFileInfo& manifestInfo);
|
JsonCatPack(QFileInfo& manifestInfo);
|
||||||
virtual QString path();
|
virtual QString path() override;
|
||||||
|
QString path(QDate now);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_defaultPath;
|
QString m_defaultPath;
|
||||||
|
@ -158,12 +158,12 @@ QString InfoFrame::renderColorCodes(QString input)
|
|||||||
//
|
//
|
||||||
// TODO: Wrap links inside <a> tags
|
// TODO: Wrap links inside <a> tags
|
||||||
|
|
||||||
// https://minecraft.fandom.com/wiki/Formatting_codes#Color_codes
|
// https://minecraft.wiki/w/Formatting_codes#Color_codes
|
||||||
const QMap<QChar, QString> color_codes_map = { { '0', "#000000" }, { '1', "#0000AA" }, { '2', "#00AA00" }, { '3', "#00AAAA" },
|
const QMap<QChar, QString> color_codes_map = { { '0', "#000000" }, { '1', "#0000AA" }, { '2', "#00AA00" }, { '3', "#00AAAA" },
|
||||||
{ '4', "#AA0000" }, { '5', "#AA00AA" }, { '6', "#FFAA00" }, { '7', "#AAAAAA" },
|
{ '4', "#AA0000" }, { '5', "#AA00AA" }, { '6', "#FFAA00" }, { '7', "#AAAAAA" },
|
||||||
{ '8', "#555555" }, { '9', "#5555FF" }, { 'a', "#55FF55" }, { 'b', "#55FFFF" },
|
{ '8', "#555555" }, { '9', "#5555FF" }, { 'a', "#55FF55" }, { 'b', "#55FFFF" },
|
||||||
{ 'c', "#FF5555" }, { 'd', "#FF55FF" }, { 'e', "#FFFF55" }, { 'f', "#FFFFFF" } };
|
{ 'c', "#FF5555" }, { 'd', "#FF55FF" }, { 'e', "#FFFF55" }, { 'f', "#FFFFFF" } };
|
||||||
// https://minecraft.fandom.com/wiki/Formatting_codes#Formatting_codes
|
// https://minecraft.wiki/w/Formatting_codes#Formatting_codes
|
||||||
const QMap<QChar, QString> formatting_codes_map = { { 'l', "b" }, { 'm', "s" }, { 'n', "u" }, { 'o', "i" } };
|
const QMap<QChar, QString> formatting_codes_map = { { 'l', "b" }, { 'm', "s" }, { 'n', "u" }, { 'o', "i" } };
|
||||||
|
|
||||||
QString html("<html>");
|
QString html("<html>");
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
packages = let
|
packages = let
|
||||||
ourPackages = lib.fix (final: self.overlays.default ({inherit (pkgs) darwin;} // final) pkgs);
|
ourPackages = lib.fix (final: self.overlays.default final pkgs);
|
||||||
in {
|
in {
|
||||||
inherit
|
inherit
|
||||||
(ourPackages)
|
(ourPackages)
|
||||||
@ -26,19 +26,40 @@
|
|||||||
overlays.default = final: prev: let
|
overlays.default = final: prev: let
|
||||||
version = builtins.substring 0 8 self.lastModifiedDate or "dirty";
|
version = builtins.substring 0 8 self.lastModifiedDate or "dirty";
|
||||||
|
|
||||||
|
filteredSelf = inputs.nix-filter.lib.filter {
|
||||||
|
root = ../.;
|
||||||
|
include = [
|
||||||
|
"buildconfig"
|
||||||
|
"cmake"
|
||||||
|
"launcher"
|
||||||
|
"libraries"
|
||||||
|
"program_info"
|
||||||
|
"tests"
|
||||||
|
../COPYING.md
|
||||||
|
../CMakeLists.txt
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# common args for prismlauncher evaluations
|
# common args for prismlauncher evaluations
|
||||||
unwrappedArgs = {
|
unwrappedArgs = {
|
||||||
|
self = filteredSelf;
|
||||||
|
|
||||||
inherit (inputs) libnbtplusplus;
|
inherit (inputs) libnbtplusplus;
|
||||||
inherit (final.darwin.apple_sdk.frameworks) Cocoa;
|
inherit ((final.darwin or prev.darwin).apple_sdk.frameworks) Cocoa;
|
||||||
inherit self version;
|
inherit version;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
prismlauncher-qt5-unwrapped = prev.libsForQt5.callPackage ./pkg unwrappedArgs;
|
prismlauncher-qt5-unwrapped = prev.libsForQt5.callPackage ./pkg unwrappedArgs;
|
||||||
|
|
||||||
prismlauncher-qt5 = prev.libsForQt5.callPackage ./pkg/wrapper.nix {
|
prismlauncher-qt5 = prev.libsForQt5.callPackage ./pkg/wrapper.nix {
|
||||||
prismlauncher-unwrapped = final.prismlauncher-qt5-unwrapped;
|
prismlauncher-unwrapped = final.prismlauncher-qt5-unwrapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
prismlauncher-unwrapped = prev.qt6Packages.callPackage ./pkg unwrappedArgs;
|
prismlauncher-unwrapped = prev.qt6Packages.callPackage ./pkg unwrappedArgs;
|
||||||
prismlauncher = prev.qt6Packages.callPackage ./pkg/wrapper.nix {inherit (final) prismlauncher-unwrapped;};
|
|
||||||
|
prismlauncher = prev.qt6Packages.callPackage ./pkg/wrapper.nix {
|
||||||
|
inherit (final) prismlauncher-unwrapped;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ assert lib.assertMsg (stdenv.isLinux || !gamemodeSupport) "gamemodeSupport is on
|
|||||||
dontWrapQtApps = true;
|
dontWrapQtApps = true;
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
|
mainProgram = "prismlauncher";
|
||||||
homepage = "https://prismlauncher.org/";
|
homepage = "https://prismlauncher.org/";
|
||||||
description = "A free, open source launcher for Minecraft";
|
description = "A free, open source launcher for Minecraft";
|
||||||
longDescription = ''
|
longDescription = ''
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
flite,
|
flite,
|
||||||
mesa-demos,
|
mesa-demos,
|
||||||
udev,
|
udev,
|
||||||
|
libusb1,
|
||||||
msaClientID ? null,
|
msaClientID ? null,
|
||||||
gamemodeSupport ? stdenv.isLinux,
|
gamemodeSupport ? stdenv.isLinux,
|
||||||
textToSpeechSupport ? stdenv.isLinux,
|
textToSpeechSupport ? stdenv.isLinux,
|
||||||
|
controllerSupport ? stdenv.isLinux,
|
||||||
jdks ? [jdk17 jdk8],
|
jdks ? [jdk17 jdk8],
|
||||||
additionalLibs ? [],
|
additionalLibs ? [],
|
||||||
additionalPrograms ? [],
|
additionalPrograms ? [],
|
||||||
@ -71,6 +73,7 @@ in
|
|||||||
]
|
]
|
||||||
++ lib.optional gamemodeSupport gamemode.lib
|
++ lib.optional gamemodeSupport gamemode.lib
|
||||||
++ lib.optional textToSpeechSupport flite
|
++ lib.optional textToSpeechSupport flite
|
||||||
|
++ lib.optional controllerSupport libusb1
|
||||||
++ additionalLibs;
|
++ additionalLibs;
|
||||||
|
|
||||||
runtimePrograms =
|
runtimePrograms =
|
||||||
|
@ -56,3 +56,6 @@ ecm_add_test(Index_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}:
|
|||||||
|
|
||||||
ecm_add_test(Version_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
|
ecm_add_test(Version_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
|
||||||
TEST_NAME Version)
|
TEST_NAME Version)
|
||||||
|
|
||||||
|
ecm_add_test(CatPack_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
|
||||||
|
TEST_NAME CatPack)
|
||||||
|
40
tests/CatPack_test.cpp
Normal file
40
tests/CatPack_test.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
#include <QDate>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QList>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
#include "FileSystem.h"
|
||||||
|
#include "ui/themes/CatPack.h"
|
||||||
|
|
||||||
|
class CatPackTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void test_catPack()
|
||||||
|
{
|
||||||
|
auto dataDir = QDir(QFINDTESTDATA("testdata/CatPacks")).absolutePath();
|
||||||
|
auto fileName = FS::PathCombine(dataDir, "index.json");
|
||||||
|
auto fileinfo = QFileInfo(fileName);
|
||||||
|
try {
|
||||||
|
auto cat = JsonCatPack(fileinfo);
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 4, 12)), FS::PathCombine(fileinfo.path(), "oneDay.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 4, 11)), FS::PathCombine(fileinfo.path(), "maxwell.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 4, 13)), FS::PathCombine(fileinfo.path(), "maxwell.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 12, 21)), FS::PathCombine(fileinfo.path(), "christmas.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 12, 28)), FS::PathCombine(fileinfo.path(), "christmas.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 12, 29)), FS::PathCombine(fileinfo.path(), "newyear.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 12, 30)), FS::PathCombine(fileinfo.path(), "newyear2.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2023, 12, 31)), FS::PathCombine(fileinfo.path(), "newyear2.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2024, 1, 1)), FS::PathCombine(fileinfo.path(), "newyear2.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2024, 1, 2)), FS::PathCombine(fileinfo.path(), "newyear.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2024, 1, 3)), FS::PathCombine(fileinfo.path(), "newyear.png"));
|
||||||
|
QCOMPARE(cat.path(QDate(2024, 1, 4)), FS::PathCombine(fileinfo.path(), "maxwell.png"));
|
||||||
|
} catch (const Exception& e) {
|
||||||
|
QFAIL(e.cause().toLatin1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(CatPackTest)
|
||||||
|
|
||||||
|
#include "CatPack_test.moc"
|
50
tests/testdata/CatPacks/index.json
vendored
Normal file
50
tests/testdata/CatPacks/index.json
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"name": "My Cute Cat",
|
||||||
|
"default": "maxwell.png",
|
||||||
|
"variants": [
|
||||||
|
{
|
||||||
|
"startTime": {
|
||||||
|
"day": 12,
|
||||||
|
"month": 4
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"day": 12,
|
||||||
|
"month": 4
|
||||||
|
},
|
||||||
|
"path": "oneDay.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startTime": {
|
||||||
|
"day": 20,
|
||||||
|
"month": 12
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"day": 28,
|
||||||
|
"month": 12
|
||||||
|
},
|
||||||
|
"path": "christmas.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startTime": {
|
||||||
|
"day": 30,
|
||||||
|
"month": 12
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"day": 1,
|
||||||
|
"month": 1
|
||||||
|
},
|
||||||
|
"path": "newyear2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startTime": {
|
||||||
|
"day": 28,
|
||||||
|
"month": 12
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"day": 3,
|
||||||
|
"month": 1
|
||||||
|
},
|
||||||
|
"path": "newyear.png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user