Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into curse_multiple_loaders2

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2023-08-27 15:53:35 +03:00
commit c5aac24a93
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
17 changed files with 103 additions and 73 deletions

1
.envrc
View File

@ -1 +1,2 @@
use flake use flake
watch_file nix/*.nix

View File

@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22 - uses: cachix/install-nix-action@v22
- uses: DeterminateSystems/update-flake-lock@v19 - uses: DeterminateSystems/update-flake-lock@v20
with: with:
commit-msg: "chore(nix): update lockfile" commit-msg: "chore(nix): update lockfile"
pr-title: "chore(nix): update lockfile" pr-title: "chore(nix): update lockfile"

View File

@ -91,11 +91,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1692463654, "lastModified": 1693060755,
"narHash": "sha256-F8hZmsQINI+S6UROM4jyxAMbQLtzE44pI8Nk6NtMdao=", "narHash": "sha256-KNsbfqewEziFJEpPR0qvVz4rx0x6QXxw1CcunRhlFdk=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ca3c9ac9f4cdd4bea19f592b32bb59b74ab7d783", "rev": "c66ccfa00c643751da2fd9290e096ceaa30493fc",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -103,14 +103,8 @@ class Version {
QString m_fullString; QString m_fullString;
[[nodiscard]] inline bool isAppendix() const [[nodiscard]] inline bool isAppendix() const { return m_stringPart.startsWith('+'); }
{ [[nodiscard]] inline bool isPreRelease() const { return m_stringPart.startsWith('-') && m_stringPart.length() > 1; }
return m_stringPart.startsWith('+');
}
[[nodiscard]] inline bool isPreRelease() const
{
return m_stringPart.startsWith('-') && m_stringPart.length() > 1;
}
inline bool operator==(const Section& other) const inline bool operator==(const Section& other) const
{ {
@ -156,14 +150,8 @@ class Version {
return m_fullString < other.m_fullString; return m_fullString < other.m_fullString;
} }
inline bool operator!=(const Section& other) const inline bool operator!=(const Section& other) const { return !(*this == other); }
{ inline bool operator>(const Section& other) const { return !(*this < other || *this == other); }
return !(*this == other);
}
inline bool operator>(const Section& other) const
{
return !(*this < other || *this == other);
}
}; };
private: private:

View File

@ -30,7 +30,7 @@ class LogModel : public QAbstractListModel {
enum Roles { LevelRole = Qt::UserRole }; enum Roles { LevelRole = Qt::UserRole };
private /* types */: private /* types */:
struct entry { struct entry {
MessageLevel::Enum level; MessageLevel::Enum level;
QString line; QString line;

View File

@ -51,8 +51,13 @@
#include "Application.h" #include "Application.h"
#include "Json.h"
#include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/LocalModUpdateTask.h"
#include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir) ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir)
: ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed)
@ -309,3 +314,47 @@ void ModFolderModel::onParseSucceeded(int ticket, QString mod_id)
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1)); emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
} }
static const FlameAPI flameAPI;
bool ModFolderModel::installMod(QString file_path, ModPlatform::IndexedVersion& vers)
{
if (vers.addonId.isValid()) {
ModPlatform::IndexedPack pack{
vers.addonId,
ModPlatform::ResourceProvider::FLAME,
};
QEventLoop loop;
auto response = std::make_shared<QByteArray>();
auto job = flameAPI.getProject(vers.addonId.toString(), response);
QObject::connect(job.get(), &Task::failed, [&loop] { loop.quit(); });
QObject::connect(job.get(), &Task::aborted, &loop, &QEventLoop::quit);
QObject::connect(job.get(), &Task::succeeded, [response, this, &vers, &loop, &pack] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qDebug() << *response;
return;
}
try {
auto obj = Json::requireObject(Json::requireObject(doc), "data");
FlameMod::loadIndexedPack(pack, obj);
} catch (const JSONValidationError& e) {
qDebug() << doc;
qWarning() << "Error while reading mod info: " << e.cause();
}
LocalModUpdateTask update_metadata(indexDir(), pack, vers);
QObject::connect(&update_metadata, &Task::finished, &loop, &QEventLoop::quit);
update_metadata.start();
});
job->start();
loop.exec();
}
return ResourceFolderModel::installResource(file_path);
}

View File

@ -48,6 +48,7 @@
#include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h"
#include "modplatform/ModIndex.h"
class LegacyInstance; class LegacyInstance;
class BaseInstance; class BaseInstance;
@ -75,6 +76,7 @@ class ModFolderModel : public ResourceFolderModel {
[[nodiscard]] Task* createParseTask(Resource&) override; [[nodiscard]] Task* createParseTask(Resource&) override;
bool installMod(QString file_path) { return ResourceFolderModel::installResource(file_path); } bool installMod(QString file_path) { return ResourceFolderModel::installResource(file_path); }
bool installMod(QString file_path, ModPlatform::IndexedVersion& vers);
bool uninstallMod(const QString& filename, bool preserve_metadata = false); bool uninstallMod(const QString& filename, bool preserve_metadata = false);
/// Deletes all the selected mods /// Deletes all the selected mods

View File

@ -118,7 +118,9 @@
#include "minecraft/mod/TexturePackFolderModel.h" #include "minecraft/mod/TexturePackFolderModel.h"
#include "minecraft/mod/tasks/LocalResourceParse.h" #include "minecraft/mod/tasks/LocalResourceParse.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h" #include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
#include "KonamiCode.h" #include "KonamiCode.h"
@ -923,6 +925,7 @@ void MainWindow::processURLs(QList<QUrl> urls)
if (url.scheme().isEmpty()) if (url.scheme().isEmpty())
url.setScheme("file"); url.setScheme("file");
ModPlatform::IndexedVersion version;
QMap<QString, QString> extra_info; QMap<QString, QString> extra_info;
QUrl local_url; QUrl local_url;
if (!url.isLocalFile()) { // download the remote resource and identify if (!url.isLocalFile()) { // download the remote resource and identify
@ -948,20 +951,19 @@ void MainWindow::processURLs(QList<QUrl> urls)
auto api = FlameAPI(); auto api = FlameAPI();
auto job = api.getFile(addonId, fileId, array); auto job = api.getFile(addonId, fileId, array);
QString resource_name;
connect(job.get(), &Task::failed, this, connect(job.get(), &Task::failed, this,
[this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
connect(job.get(), &Task::succeeded, this, [this, array, addonId, fileId, &dl_url, &resource_name] { connect(job.get(), &Task::succeeded, this, [this, array, addonId, fileId, &dl_url, &version] {
qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str(); qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str();
auto doc = Json::requireDocument(*array); auto doc = Json::requireDocument(*array);
auto data = Json::ensureObject(Json::ensureObject(doc.object()), "data"); auto data = Json::ensureObject(Json::ensureObject(doc.object()), "data");
// No way to find out if it's a mod or a modpack before here // No way to find out if it's a mod or a modpack before here
// And also we need to check if it ends with .zip, instead of any better way // And also we need to check if it ends with .zip, instead of any better way
auto fileName = Json::ensureString(data, "fileName"); version = FlameMod::loadIndexedPackVersion(data);
auto fileName = version.fileName;
// Have to use ensureString then use QUrl to get proper url encoding // Have to use ensureString then use QUrl to get proper url encoding
dl_url = QUrl(Json::ensureString(data, "downloadUrl", "", "downloadUrl")); dl_url = QUrl(version.downloadUrl);
if (!dl_url.isValid()) { if (!dl_url.isValid()) {
CustomMessageBox::selectable( CustomMessageBox::selectable(
this, tr("Error"), this, tr("Error"),
@ -972,7 +974,6 @@ void MainWindow::processURLs(QList<QUrl> urls)
} }
QFileInfo dl_file(dl_url.fileName()); QFileInfo dl_file(dl_url.fileName());
resource_name = Json::ensureString(data, "displayName", dl_file.completeBaseName(), "displayName");
}); });
{ // drop stack { // drop stack
@ -1047,7 +1048,7 @@ void MainWindow::processURLs(QList<QUrl> urls)
qWarning() << "Importing of Data Packs not supported at this time. Ignoring" << localFileName; qWarning() << "Importing of Data Packs not supported at this time. Ignoring" << localFileName;
break; break;
case PackedResourceType::Mod: case PackedResourceType::Mod:
minecraftInst->loaderModList()->installMod(localFileName); minecraftInst->loaderModList()->installMod(localFileName, version);
break; break;
case PackedResourceType::ShaderPack: case PackedResourceType::ShaderPack:
minecraftInst->shaderPackList()->installResource(localFileName); minecraftInst->shaderPackList()->installResource(localFileName);

View File

@ -151,10 +151,7 @@ class MainWindow : public QMainWindow {
void deleteGroup(); void deleteGroup();
void undoTrashInstance(); void undoTrashInstance();
inline void on_actionExportInstance_triggered() inline void on_actionExportInstance_triggered() { on_actionExportInstanceZip_triggered(); }
{
on_actionExportInstanceZip_triggered();
}
void on_actionExportInstanceZip_triggered(); void on_actionExportInstanceZip_triggered();
void on_actionExportInstanceMrPack_triggered(); void on_actionExportInstanceMrPack_triggered();
void on_actionExportInstanceFlamePack_triggered(); void on_actionExportInstanceFlamePack_triggered();

View File

@ -185,6 +185,7 @@ void JavaPage::updateThresholds()
{ {
auto sysMiB = Sys::getSystemRam() / Sys::mebibyte; auto sysMiB = Sys::getSystemRam() / Sys::mebibyte;
unsigned int maxMem = ui->maxMemSpinBox->value(); unsigned int maxMem = ui->maxMemSpinBox->value();
unsigned int minMem = ui->minMemSpinBox->value();
QString iconName; QString iconName;
@ -194,6 +195,9 @@ void JavaPage::updateThresholds()
} else if (maxMem > (sysMiB * 0.9)) { } else if (maxMem > (sysMiB * 0.9)) {
iconName = "status-yellow"; iconName = "status-yellow";
ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity.")); ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity."));
} else if (maxMem < minMem) {
iconName = "status-yellow";
ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value"));
} else { } else {
iconName = "status-good"; iconName = "status-good";
ui->labelMaxMemIcon->setToolTip(""); ui->labelMaxMemIcon->setToolTip("");

View File

@ -478,6 +478,7 @@ void InstanceSettingsPage::updateThresholds()
{ {
auto sysMiB = Sys::getSystemRam() / Sys::mebibyte; auto sysMiB = Sys::getSystemRam() / Sys::mebibyte;
unsigned int maxMem = ui->maxMemSpinBox->value(); unsigned int maxMem = ui->maxMemSpinBox->value();
unsigned int minMem = ui->minMemSpinBox->value();
QString iconName; QString iconName;
@ -487,6 +488,9 @@ void InstanceSettingsPage::updateThresholds()
} else if (maxMem > (sysMiB * 0.9)) { } else if (maxMem > (sysMiB * 0.9)) {
iconName = "status-yellow"; iconName = "status-yellow";
ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity.")); ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity."));
} else if (maxMem < minMem) {
iconName = "status-yellow";
ui->labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value"));
} else { } else {
iconName = "status-good"; iconName = "status-good";
ui->labelMaxMemIcon->setToolTip(""); ui->labelMaxMemIcon->setToolTip("");

View File

@ -354,14 +354,8 @@ class ServersModel : public QAbstractListModel {
} }
} }
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override { return parent.isValid() ? 0 : m_servers.size(); }
{ int columnCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : COLUMN_COUNT; }
return parent.isValid() ? 0 : m_servers.size();
}
int columnCount(const QModelIndex& parent) const override
{
return parent.isValid() ? 0 : COLUMN_COUNT;
}
Server* at(int index) Server* at(int index)
{ {
@ -445,10 +439,7 @@ class ServersModel : public QAbstractListModel {
qDebug() << "Changed:" << path; qDebug() << "Changed:" << path;
load(); load();
} }
void fileChanged(const QString& path) void fileChanged(const QString& path) { qDebug() << "Changed:" << path; }
{
qDebug() << "Changed:" << path;
}
private slots: private slots:
void save_internal() void save_internal()
@ -492,10 +483,7 @@ class ServersModel : public QAbstractListModel {
m_saveTimer.stop(); m_saveTimer.stop();
} }
bool saveIsScheduled() const bool saveIsScheduled() const { return m_dirty; }
{
return m_dirty;
}
void updateFSObserver() void updateFSObserver()
{ {

View File

@ -186,12 +186,20 @@ QString JavaSettingsWidget::javaPath() const
int JavaSettingsWidget::maxHeapSize() const int JavaSettingsWidget::maxHeapSize() const
{ {
return m_maxMemSpinBox->value(); auto min = m_minMemSpinBox->value();
auto max = m_maxMemSpinBox->value();
if (max < min)
max = min;
return max;
} }
int JavaSettingsWidget::minHeapSize() const int JavaSettingsWidget::minHeapSize() const
{ {
return m_minMemSpinBox->value(); auto min = m_minMemSpinBox->value();
auto max = m_maxMemSpinBox->value();
if (min > max)
min = max;
return min;
} }
bool JavaSettingsWidget::permGenEnabled() const bool JavaSettingsWidget::permGenEnabled() const
@ -214,17 +222,9 @@ void JavaSettingsWidget::memoryValueChanged(int)
if (obj == m_minMemSpinBox && min != observedMinMemory) { if (obj == m_minMemSpinBox && min != observedMinMemory) {
observedMinMemory = min; observedMinMemory = min;
actuallyChanged = true; actuallyChanged = true;
if (min > max) {
observedMaxMemory = min;
m_maxMemSpinBox->setValue(min);
}
} else if (obj == m_maxMemSpinBox && max != observedMaxMemory) { } else if (obj == m_maxMemSpinBox && max != observedMaxMemory) {
observedMaxMemory = max; observedMaxMemory = max;
actuallyChanged = true; actuallyChanged = true;
if (min > max) {
observedMinMemory = max;
m_minMemSpinBox->setValue(max);
}
} else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory) { } else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory) {
observedPermGenMemory = permgen; observedPermGenMemory = permgen;
actuallyChanged = true; actuallyChanged = true;
@ -361,8 +361,8 @@ void JavaSettingsWidget::checkJavaPath(const QString& path)
setJavaStatus(JavaStatus::Pending); setJavaStatus(JavaStatus::Pending);
m_checker.reset(new JavaChecker()); m_checker.reset(new JavaChecker());
m_checker->m_path = path; m_checker->m_path = path;
m_checker->m_minMem = m_minMemSpinBox->value(); m_checker->m_minMem = minHeapSize();
m_checker->m_maxMem = m_maxMemSpinBox->value(); m_checker->m_maxMem = maxHeapSize();
if (m_permGenSpinBox->isVisible()) { if (m_permGenSpinBox->isVisible()) {
m_checker->m_permGen = m_permGenSpinBox->value(); m_checker->m_permGen = m_permGenSpinBox->value();
} }
@ -415,6 +415,9 @@ void JavaSettingsWidget::updateThresholds()
} else if (observedMaxMemory > (m_availableMemory * 0.9)) { } else if (observedMaxMemory > (m_availableMemory * 0.9)) {
iconName = "status-yellow"; iconName = "status-yellow";
m_labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity.")); m_labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation approaches your system memory capacity."));
} else if (observedMaxMemory < observedMinMemory) {
iconName = "status-yellow";
m_labelMaxMemIcon->setToolTip(tr("Your maximum memory allocation is smaller than the minimum value"));
} else { } else {
iconName = "status-good"; iconName = "status-good";
m_labelMaxMemIcon->setToolTip(""); m_labelMaxMemIcon->setToolTip("");

View File

@ -220,5 +220,5 @@ void LocalPeer::receiveConnection()
socket->waitForBytesWritten(1000); socket->waitForBytesWritten(1000);
socket->waitForDisconnected(1000); // make sure client reads ack socket->waitForDisconnected(1000); // make sure client reads ack
delete socket; delete socket;
emit messageReceived(uMsg); //### (might take a long time to return) emit messageReceived(uMsg); // ### (might take a long time to return)
} }

View File

@ -23,18 +23,13 @@
types_or = ["c" "c++" "java" "json" "objective-c"]; types_or = ["c" "c++" "java" "json" "objective-c"];
}; };
}; };
tools.clang-tools = pkgs.clang-tools_16;
}; };
}; };
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
inherit (self.checks.${system}.pre-commit-check) shellHook; inherit (self.checks.${system}.pre-commit-check) shellHook;
packages = with pkgs; [
nodePackages.markdownlint-cli
alejandra
deadnix
clang-tools
nil
];
inputsFrom = [self.packages.${system}.prismlauncher-unwrapped]; inputsFrom = [self.packages.${system}.prismlauncher-unwrapped];
buildInputs = with pkgs; [ccache ninja]; buildInputs = with pkgs; [ccache ninja];

View File

@ -1,6 +1,7 @@
{ {
lib, lib,
stdenv, stdenv,
canonicalize-jars-hook,
cmake, cmake,
cmark, cmark,
Cocoa, Cocoa,
@ -26,7 +27,7 @@ assert lib.assertMsg (stdenv.isLinux || !gamemodeSupport) "gamemodeSupport is on
src = lib.cleanSource self; src = lib.cleanSource self;
nativeBuildInputs = [extra-cmake-modules cmake jdk17 ninja]; nativeBuildInputs = [extra-cmake-modules cmake jdk17 ninja canonicalize-jars-hook];
buildInputs = buildInputs =
[ [
qtbase qtbase

View File

@ -353,10 +353,7 @@ class FileSystemTest : public QObject {
} }
} }
void test_getDesktop() void test_getDesktop() { QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); }
{
QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
}
void test_link() void test_link()
{ {