Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feature/java-downloader
This commit is contained in:
commit
1322277ae6
1
.github/workflows/backport.yml
vendored
1
.github/workflows/backport.yml
vendored
@ -16,6 +16,7 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write # for korthout/backport-action to create branch
|
contents: write # for korthout/backport-action to create branch
|
||||||
pull-requests: write # for korthout/backport-action to create PR to backport
|
pull-requests: write # for korthout/backport-action to create PR to backport
|
||||||
|
actions: write # for korthout/backport-action to create PR with workflow changes
|
||||||
name: Backport Pull Request
|
name: Backport Pull Request
|
||||||
if: github.repository_owner == 'PrismLauncher' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
|
if: github.repository_owner == 'PrismLauncher' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -166,7 +166,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@v4.0.0
|
uses: actions/cache@v4.0.1
|
||||||
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 }}
|
||||||
@ -407,7 +407,7 @@ jobs:
|
|||||||
if [ '${{ secrets.SPARKLE_ED25519_KEY }}' != '' ]; then
|
if [ '${{ secrets.SPARKLE_ED25519_KEY }}' != '' ]; then
|
||||||
brew install openssl@3
|
brew install openssl@3
|
||||||
echo '${{ secrets.SPARKLE_ED25519_KEY }}' > ed25519-priv.pem
|
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=$(/usr/local/opt/openssl@3/bin/openssl pkeyutl -sign -rawin -in ${{ github.workspace }}/PrismLauncher.zip -inkey ed25519-priv.pem | openssl base64 | tr -d \\n)
|
||||||
rm ed25519-priv.pem
|
rm ed25519-priv.pem
|
||||||
cat >> $GITHUB_STEP_SUMMARY << EOF
|
cat >> $GITHUB_STEP_SUMMARY << EOF
|
||||||
### Artifact Information :information_source:
|
### Artifact Information :information_source:
|
||||||
|
2
.github/workflows/trigger_release.yml
vendored
2
.github/workflows/trigger_release.yml
vendored
@ -84,7 +84,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
tag_name: ${{ github.ref }}
|
tag_name: ${{ github.ref }}
|
||||||
|
4
.github/workflows/update-flake.yml
vendored
4
.github/workflows/update-flake.yml
vendored
@ -17,9 +17,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: cachix/install-nix-action@6004951b182f8860210c8d6f0d808ec5b1a33d28 # v25
|
- uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26
|
||||||
|
|
||||||
- uses: DeterminateSystems/update-flake-lock@v20
|
- uses: DeterminateSystems/update-flake-lock@v21
|
||||||
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"
|
||||||
|
@ -178,7 +178,7 @@ set(Launcher_NEWS_OPEN_URL "https://prismlauncher.org/news" CACHE STRING "URL th
|
|||||||
set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
|
set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
|
||||||
|
|
||||||
######## Set version numbers ########
|
######## Set version numbers ########
|
||||||
set(Launcher_VERSION_MAJOR 8)
|
set(Launcher_VERSION_MAJOR 9)
|
||||||
set(Launcher_VERSION_MINOR 0)
|
set(Launcher_VERSION_MINOR 0)
|
||||||
|
|
||||||
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
|
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
|
||||||
|
12
flake.lock
generated
12
flake.lock
generated
@ -23,11 +23,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1706830856,
|
"lastModified": 1709336216,
|
||||||
"narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=",
|
"narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f",
|
"rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -93,11 +93,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708151420,
|
"lastModified": 1710534455,
|
||||||
"narHash": "sha256-MGT/4aGCWQPQiu6COqJdCj9kSpLPiShgbwpbC38YXC8=",
|
"narHash": "sha256-huQT4Xs0y4EeFKn2BTBVYgEwJSv8SDlm82uWgMnCMmI=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6e2f00c83911461438301db0dba5281197fe4b3a",
|
"rev": "9af9c1c87ed3e3ed271934cb896e0cdd33dae212",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -644,10 +644,11 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
|||||||
m_settings->registerSetting("UseNativeGLFW", false);
|
m_settings->registerSetting("UseNativeGLFW", false);
|
||||||
m_settings->registerSetting("CustomGLFWPath", "");
|
m_settings->registerSetting("CustomGLFWPath", "");
|
||||||
|
|
||||||
// Peformance related options
|
// Performance related options
|
||||||
m_settings->registerSetting("EnableFeralGamemode", false);
|
m_settings->registerSetting("EnableFeralGamemode", false);
|
||||||
m_settings->registerSetting("EnableMangoHud", false);
|
m_settings->registerSetting("EnableMangoHud", false);
|
||||||
m_settings->registerSetting("UseDiscreteGpu", false);
|
m_settings->registerSetting("UseDiscreteGpu", false);
|
||||||
|
m_settings->registerSetting("UseZink", false);
|
||||||
|
|
||||||
// Game time
|
// Game time
|
||||||
m_settings->registerSetting("ShowGameTime", true);
|
m_settings->registerSetting("ShowGameTime", true);
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
@ -847,14 +848,16 @@ class InstanceStaging : public Task {
|
|||||||
const unsigned maxBackoff = 16;
|
const unsigned maxBackoff = 16;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InstanceStaging(InstanceList* parent, InstanceTask* child, QString stagingPath, InstanceName const& instanceName, QString groupName)
|
InstanceStaging(InstanceList* parent, InstanceTask* child, SettingsObjectPtr settings)
|
||||||
: m_parent(parent)
|
: m_parent(parent), backoff(minBackoff, maxBackoff)
|
||||||
, backoff(minBackoff, maxBackoff)
|
|
||||||
, m_stagingPath(std::move(stagingPath))
|
|
||||||
, m_instance_name(std::move(instanceName))
|
|
||||||
, m_groupName(std::move(groupName))
|
|
||||||
{
|
{
|
||||||
|
m_stagingPath = parent->getStagedInstancePath();
|
||||||
|
|
||||||
m_child.reset(child);
|
m_child.reset(child);
|
||||||
|
|
||||||
|
m_child->setStagingPath(m_stagingPath);
|
||||||
|
m_child->setParentSettings(std::move(settings));
|
||||||
|
|
||||||
connect(child, &Task::succeeded, this, &InstanceStaging::childSucceeded);
|
connect(child, &Task::succeeded, this, &InstanceStaging::childSucceeded);
|
||||||
connect(child, &Task::failed, this, &InstanceStaging::childFailed);
|
connect(child, &Task::failed, this, &InstanceStaging::childFailed);
|
||||||
connect(child, &Task::aborted, this, &InstanceStaging::childAborted);
|
connect(child, &Task::aborted, this, &InstanceStaging::childAborted);
|
||||||
@ -866,7 +869,7 @@ class InstanceStaging : public Task {
|
|||||||
connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceeded);
|
connect(&m_backoffTimer, &QTimer::timeout, this, &InstanceStaging::childSucceeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~InstanceStaging(){};
|
virtual ~InstanceStaging() {}
|
||||||
|
|
||||||
// FIXME/TODO: add ability to abort during instance commit retries
|
// FIXME/TODO: add ability to abort during instance commit retries
|
||||||
bool abort() override
|
bool abort() override
|
||||||
@ -881,14 +884,22 @@ class InstanceStaging : public Task {
|
|||||||
bool canAbort() const override { return (m_child && m_child->canAbort()); }
|
bool canAbort() const override { return (m_child && m_child->canAbort()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void executeTask() override { m_child->start(); }
|
virtual void executeTask() override
|
||||||
|
{
|
||||||
|
if (m_stagingPath.isNull()) {
|
||||||
|
emitFailed(tr("Could not create staging folder"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_child->start();
|
||||||
|
}
|
||||||
QStringList warnings() const override { return m_child->warnings(); }
|
QStringList warnings() const override { return m_child->warnings(); }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void childSucceeded()
|
void childSucceeded()
|
||||||
{
|
{
|
||||||
unsigned sleepTime = backoff();
|
unsigned sleepTime = backoff();
|
||||||
if (m_parent->commitStagedInstance(m_stagingPath, m_instance_name, m_groupName, *m_child.get())) {
|
if (m_parent->commitStagedInstance(m_stagingPath, *m_child.get(), m_child->group(), *m_child.get())) {
|
||||||
emitSucceeded();
|
emitSucceeded();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -897,7 +908,7 @@ class InstanceStaging : public Task {
|
|||||||
emitFailed(tr("Failed to commit instance, even after multiple retries. It is being blocked by something."));
|
emitFailed(tr("Failed to commit instance, even after multiple retries. It is being blocked by something."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "Failed to commit instance" << m_instance_name.name() << "Initiating backoff:" << sleepTime;
|
qDebug() << "Failed to commit instance" << m_child->name() << "Initiating backoff:" << sleepTime;
|
||||||
m_backoffTimer.start(sleepTime * 500);
|
m_backoffTimer.start(sleepTime * 500);
|
||||||
}
|
}
|
||||||
void childFailed(const QString& reason)
|
void childFailed(const QString& reason)
|
||||||
@ -906,7 +917,11 @@ class InstanceStaging : public Task {
|
|||||||
emitFailed(reason);
|
emitFailed(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void childAborted() { emitAborted(); }
|
void childAborted()
|
||||||
|
{
|
||||||
|
m_parent->destroyStagingPath(m_stagingPath);
|
||||||
|
emitAborted();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InstanceList* m_parent;
|
InstanceList* m_parent;
|
||||||
@ -918,34 +933,35 @@ class InstanceStaging : public Task {
|
|||||||
ExponentialSeries backoff;
|
ExponentialSeries backoff;
|
||||||
QString m_stagingPath;
|
QString m_stagingPath;
|
||||||
unique_qobject_ptr<InstanceTask> m_child;
|
unique_qobject_ptr<InstanceTask> m_child;
|
||||||
InstanceName m_instance_name;
|
|
||||||
QString m_groupName;
|
|
||||||
QTimer m_backoffTimer;
|
QTimer m_backoffTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
Task* InstanceList::wrapInstanceTask(InstanceTask* task)
|
Task* InstanceList::wrapInstanceTask(InstanceTask* task)
|
||||||
{
|
{
|
||||||
auto stagingPath = getStagedInstancePath();
|
return new InstanceStaging(this, task, m_globalSettings);
|
||||||
task->setStagingPath(stagingPath);
|
|
||||||
task->setParentSettings(m_globalSettings);
|
|
||||||
return new InstanceStaging(this, task, stagingPath, *task, task->group());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString InstanceList::getStagedInstancePath()
|
QString InstanceList::getStagedInstancePath()
|
||||||
{
|
{
|
||||||
QString key = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
const QString tempRoot = FS::PathCombine(m_instDir, ".tmp");
|
||||||
QString tempDir = ".LAUNCHER_TEMP/";
|
|
||||||
QString relPath = FS::PathCombine(tempDir, key);
|
QString result;
|
||||||
QDir rootPath(m_instDir);
|
int tries = 0;
|
||||||
auto path = FS::PathCombine(m_instDir, relPath);
|
|
||||||
if (!rootPath.mkpath(relPath)) {
|
do {
|
||||||
return QString();
|
if (++tries > 256)
|
||||||
}
|
return {};
|
||||||
|
|
||||||
|
const QString key = QUuid::createUuid().toString(QUuid::Id128).left(6);
|
||||||
|
result = FS::PathCombine(tempRoot, key);
|
||||||
|
} while (QFileInfo::exists(result));
|
||||||
|
|
||||||
|
if (!QDir::current().mkpath(result))
|
||||||
|
return {};
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
auto tempPath = FS::PathCombine(m_instDir, tempDir);
|
SetFileAttributesA(tempRoot.toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
|
||||||
SetFileAttributesA(tempPath.toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
|
|
||||||
#endif
|
#endif
|
||||||
return path;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InstanceList::commitStagedInstance(const QString& path,
|
bool InstanceList::commitStagedInstance(const QString& path,
|
||||||
|
@ -463,7 +463,7 @@ auto ExportToZipTask::exportZip() -> ZipResult
|
|||||||
|
|
||||||
auto absolute = file.absoluteFilePath();
|
auto absolute = file.absoluteFilePath();
|
||||||
auto relative = m_dir.relativeFilePath(absolute);
|
auto relative = m_dir.relativeFilePath(absolute);
|
||||||
setStatus("Compresing: " + relative);
|
setStatus("Compressing: " + relative);
|
||||||
setProgress(m_progress + 1, m_progressTotal);
|
setProgress(m_progress + 1, m_progressTotal);
|
||||||
if (m_follow_symlinks) {
|
if (m_follow_symlinks) {
|
||||||
if (file.isSymLink())
|
if (file.isSymLink())
|
||||||
|
@ -175,11 +175,12 @@ void MinecraftInstance::loadSpecificSettings()
|
|||||||
m_settings->registerOverride(global_settings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride);
|
m_settings->registerOverride(global_settings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride);
|
||||||
m_settings->registerOverride(global_settings->getSetting("CustomGLFWPath"), nativeLibraryWorkaroundsOverride);
|
m_settings->registerOverride(global_settings->getSetting("CustomGLFWPath"), nativeLibraryWorkaroundsOverride);
|
||||||
|
|
||||||
// Peformance related options
|
// Performance related options
|
||||||
auto performanceOverride = m_settings->registerSetting("OverridePerformance", false);
|
auto performanceOverride = m_settings->registerSetting("OverridePerformance", false);
|
||||||
m_settings->registerOverride(global_settings->getSetting("EnableFeralGamemode"), performanceOverride);
|
m_settings->registerOverride(global_settings->getSetting("EnableFeralGamemode"), performanceOverride);
|
||||||
m_settings->registerOverride(global_settings->getSetting("EnableMangoHud"), performanceOverride);
|
m_settings->registerOverride(global_settings->getSetting("EnableMangoHud"), performanceOverride);
|
||||||
m_settings->registerOverride(global_settings->getSetting("UseDiscreteGpu"), performanceOverride);
|
m_settings->registerOverride(global_settings->getSetting("UseDiscreteGpu"), performanceOverride);
|
||||||
|
m_settings->registerOverride(global_settings->getSetting("UseZink"), performanceOverride);
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
auto miscellaneousOverride = m_settings->registerSetting("OverrideMiscellaneous", false);
|
auto miscellaneousOverride = m_settings->registerSetting("OverrideMiscellaneous", false);
|
||||||
@ -624,6 +625,13 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment()
|
|||||||
env.insert("__VK_LAYER_NV_optimus", "NVIDIA_only");
|
env.insert("__VK_LAYER_NV_optimus", "NVIDIA_only");
|
||||||
env.insert("__GLX_VENDOR_LIBRARY_NAME", "nvidia");
|
env.insert("__GLX_VENDOR_LIBRARY_NAME", "nvidia");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings()->get("UseZink").toBool()) {
|
||||||
|
// taken from https://wiki.archlinux.org/title/OpenGL#OpenGL_over_Vulkan_(Zink)
|
||||||
|
env.insert("__GLX_VENDOR_LIBRARY_NAME", "mesa");
|
||||||
|
env.insert("MESA_LOADER_DRIVER_OVERRIDE", "zink");
|
||||||
|
env.insert("GALLIUM_DRIVER", "zink");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
@ -287,16 +287,12 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
|||||||
env["client"] = "required";
|
env["client"] = "required";
|
||||||
env["server"] = "required";
|
env["server"] = "required";
|
||||||
}
|
}
|
||||||
switch (iterator->side) {
|
|
||||||
case Metadata::ModSide::ClientSide:
|
// a server side mod does not imply that the mod does not work on the client
|
||||||
env["server"] = "unsupported";
|
// however, if a mrpack mod is marked as server-only it will not install on the client
|
||||||
break;
|
if (iterator->side == Metadata::ModSide::ClientSide)
|
||||||
case Metadata::ModSide::ServerSide:
|
env["server"] = "unsupported";
|
||||||
env["client"] = "unsupported";
|
|
||||||
break;
|
|
||||||
case Metadata::ModSide::UniversalSide:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fileOut["env"] = env;
|
fileOut["env"] = env;
|
||||||
|
|
||||||
fileOut["path"] = path;
|
fileOut["path"] = path;
|
||||||
|
@ -47,11 +47,18 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla
|
|||||||
|
|
||||||
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
||||||
setWindowTitle(tr("Export Modrinth Pack"));
|
setWindowTitle(tr("Export Modrinth Pack"));
|
||||||
ui->summary->setText(instance->settings()->get("ExportSummary").toString());
|
|
||||||
|
ui->authorLabel->hide();
|
||||||
|
ui->author->hide();
|
||||||
|
|
||||||
|
ui->summary->setPlainText(instance->settings()->get("ExportSummary").toString());
|
||||||
} else {
|
} else {
|
||||||
setWindowTitle(tr("Export CurseForge Pack"));
|
setWindowTitle(tr("Export CurseForge Pack"));
|
||||||
ui->summaryLabel->setText(tr("&Author"));
|
|
||||||
ui->summary->setText(instance->settings()->get("ExportAuthor").toString());
|
ui->summaryLabel->hide();
|
||||||
|
ui->summary->hide();
|
||||||
|
|
||||||
|
ui->author->setText(instance->settings()->get("ExportAuthor").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure a valid pack is generated
|
// ensure a valid pack is generated
|
||||||
@ -108,9 +115,13 @@ void ExportPackDialog::done(int result)
|
|||||||
auto settings = instance->settings();
|
auto settings = instance->settings();
|
||||||
settings->set("ExportName", ui->name->text());
|
settings->set("ExportName", ui->name->text());
|
||||||
settings->set("ExportVersion", ui->version->text());
|
settings->set("ExportVersion", ui->version->text());
|
||||||
settings->set(m_provider == ModPlatform::ResourceProvider::FLAME ? "ExportAuthor" : "ExportSummary", ui->summary->text());
|
|
||||||
settings->set("ExportOptionalFiles", ui->optionalFiles->isChecked());
|
settings->set("ExportOptionalFiles", ui->optionalFiles->isChecked());
|
||||||
|
|
||||||
|
if (m_provider == ModPlatform::ResourceProvider::MODRINTH)
|
||||||
|
settings->set("ExportSummary", ui->summary->toPlainText());
|
||||||
|
else
|
||||||
|
settings->set("ExportAuthor", ui->author->text());
|
||||||
|
|
||||||
if (result == Accepted) {
|
if (result == Accepted) {
|
||||||
const QString name = ui->name->text().isEmpty() ? instance->name() : ui->name->text();
|
const QString name = ui->name->text().isEmpty() ? instance->name() : ui->name->text();
|
||||||
const QString filename = FS::RemoveInvalidFilenameChars(name);
|
const QString filename = FS::RemoveInvalidFilenameChars(name);
|
||||||
@ -134,10 +145,10 @@ void ExportPackDialog::done(int result)
|
|||||||
|
|
||||||
Task* task;
|
Task* task;
|
||||||
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
|
||||||
task = new ModrinthPackExportTask(name, ui->version->text(), ui->summary->text(), ui->optionalFiles->isChecked(), instance,
|
task = new ModrinthPackExportTask(name, ui->version->text(), ui->summary->toPlainText(), ui->optionalFiles->isChecked(),
|
||||||
output, std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
instance, output, std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
||||||
} else {
|
} else {
|
||||||
task = new FlamePackExportTask(name, ui->version->text(), ui->summary->text(), ui->optionalFiles->isChecked(), instance, output,
|
task = new FlamePackExportTask(name, ui->version->text(), ui->author->text(), ui->optionalFiles->isChecked(), instance, output,
|
||||||
std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>650</width>
|
<width>650</width>
|
||||||
<height>510</height>
|
<height>532</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeGripEnabled">
|
<property name="sizeGripEnabled">
|
||||||
@ -19,21 +19,8 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&Description</string>
|
<string>&Description</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item row="3" column="0">
|
<item>
|
||||||
<widget class="QLabel" name="summaryLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Summary</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>summary</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLineEdit" name="summary"/>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="nameLabel">
|
<widget class="QLabel" name="nameLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Name</string>
|
<string>&Name</string>
|
||||||
@ -43,7 +30,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item>
|
||||||
|
<widget class="QLineEdit" name="name"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QLabel" name="versionLabel">
|
<widget class="QLabel" name="versionLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Version</string>
|
<string>&Version</string>
|
||||||
@ -53,16 +43,43 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item>
|
||||||
<widget class="QLineEdit" name="name"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="version">
|
<widget class="QLineEdit" name="version">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>1.0.0</string>
|
<string>1.0.0</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="summaryLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Summary</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>summary</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="summary">
|
||||||
|
<property name="tabChangesFocus">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="authorLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Author</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>author</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="author"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -124,6 +141,7 @@
|
|||||||
<tabstop>name</tabstop>
|
<tabstop>name</tabstop>
|
||||||
<tabstop>version</tabstop>
|
<tabstop>version</tabstop>
|
||||||
<tabstop>summary</tabstop>
|
<tabstop>summary</tabstop>
|
||||||
|
<tabstop>author</tabstop>
|
||||||
<tabstop>files</tabstop>
|
<tabstop>files</tabstop>
|
||||||
<tabstop>optionalFiles</tabstop>
|
<tabstop>optionalFiles</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
@ -482,32 +482,42 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
|||||||
|
|
||||||
if (model()->rowCount() == 0) {
|
if (model()->rowCount() == 0) {
|
||||||
painter.save();
|
painter.save();
|
||||||
const QString line1 = tr("Welcome!");
|
QString emptyString = tr("Welcome!") + "\n" + tr("Click \"Add Instance\" to get started.");
|
||||||
const QString line2 = tr("Click \"Add Instance\" to get started.");
|
|
||||||
auto rect = this->viewport()->rect();
|
|
||||||
auto font = option.font;
|
|
||||||
font.setPointSize(37);
|
|
||||||
painter.setFont(font);
|
|
||||||
auto fm = painter.fontMetrics();
|
|
||||||
|
|
||||||
if (rect.height() <= (fm.height() * 5) || rect.width() <= fm.horizontalAdvance(line2)) {
|
// calculate the rect for the overlay
|
||||||
auto s = rect.height() / (5. * fm.height());
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
auto sx = rect.width() * 1. / fm.horizontalAdvance(line2);
|
QFont font("sans", 20);
|
||||||
if (s >= sx)
|
font.setBold(true);
|
||||||
s = sx;
|
|
||||||
auto ps = font.pointSize() * s;
|
QRect bounds = viewport()->geometry();
|
||||||
if (ps <= 0)
|
bounds.moveTop(0);
|
||||||
ps = 1;
|
auto innerBounds = bounds;
|
||||||
font.setPointSize(ps);
|
innerBounds.adjust(10, 10, -10, -10);
|
||||||
painter.setFont(font);
|
|
||||||
fm = painter.fontMetrics();
|
QColor background = QApplication::palette().color(QPalette::WindowText);
|
||||||
|
QColor foreground = QApplication::palette().color(QPalette::Base);
|
||||||
|
foreground.setAlpha(190);
|
||||||
|
painter.setFont(font);
|
||||||
|
auto fontMetrics = painter.fontMetrics();
|
||||||
|
auto textRect = fontMetrics.boundingRect(innerBounds, Qt::AlignHCenter | Qt::TextWordWrap, emptyString);
|
||||||
|
textRect.moveCenter(bounds.center());
|
||||||
|
|
||||||
|
auto wrapRect = textRect;
|
||||||
|
wrapRect.adjust(-10, -10, 10, 10);
|
||||||
|
|
||||||
|
// check if we are allowed to draw in our area
|
||||||
|
if (!event->rect().intersects(wrapRect)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// text
|
painter.setBrush(QBrush(background));
|
||||||
rect.setTop(rect.top() + fm.height() * 1.5);
|
painter.setPen(foreground);
|
||||||
painter.drawText(rect, Qt::AlignHCenter, line1);
|
painter.drawRoundedRect(wrapRect, 5.0, 5.0);
|
||||||
rect.setTop(rect.top() + fm.height());
|
|
||||||
painter.drawText(rect, Qt::AlignHCenter, line2);
|
painter.setPen(foreground);
|
||||||
|
painter.setFont(font);
|
||||||
|
painter.drawText(textRect, Qt::AlignHCenter | Qt::TextWordWrap, emptyString);
|
||||||
|
|
||||||
painter.restore();
|
painter.restore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ void MinecraftPage::applySettings()
|
|||||||
s->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
s->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
||||||
s->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
s->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
||||||
s->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
s->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
||||||
|
s->set("UseZink", ui->useZink->isChecked());
|
||||||
|
|
||||||
// Game time
|
// Game time
|
||||||
s->set("ShowGameTime", ui->showGameTime->isChecked());
|
s->set("ShowGameTime", ui->showGameTime->isChecked());
|
||||||
@ -151,6 +152,7 @@ void MinecraftPage::loadSettings()
|
|||||||
ui->enableFeralGamemodeCheck->setChecked(s->get("EnableFeralGamemode").toBool());
|
ui->enableFeralGamemodeCheck->setChecked(s->get("EnableFeralGamemode").toBool());
|
||||||
ui->enableMangoHud->setChecked(s->get("EnableMangoHud").toBool());
|
ui->enableMangoHud->setChecked(s->get("EnableMangoHud").toBool());
|
||||||
ui->useDiscreteGpuCheck->setChecked(s->get("UseDiscreteGpu").toBool());
|
ui->useDiscreteGpuCheck->setChecked(s->get("UseDiscreteGpu").toBool());
|
||||||
|
ui->useZink->setChecked(s->get("UseZink").toBool());
|
||||||
|
|
||||||
#if !defined(Q_OS_LINUX)
|
#if !defined(Q_OS_LINUX)
|
||||||
ui->perfomanceGroupBox->setVisible(false);
|
ui->perfomanceGroupBox->setVisible(false);
|
||||||
|
@ -309,6 +309,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="useZink">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Use Zink, a Mesa OpenGL driver that implements OpenGL on top of Vulkan. Performance may vary depending on the situation. Note: If no suitable Vulkan driver is found, software rendering will be used.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use Zink</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -236,10 +236,13 @@ void InstanceSettingsPage::applySettings()
|
|||||||
m_settings->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
m_settings->set("EnableFeralGamemode", ui->enableFeralGamemodeCheck->isChecked());
|
||||||
m_settings->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
m_settings->set("EnableMangoHud", ui->enableMangoHud->isChecked());
|
||||||
m_settings->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
m_settings->set("UseDiscreteGpu", ui->useDiscreteGpuCheck->isChecked());
|
||||||
|
m_settings->set("UseZink", ui->useZink->isChecked());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
m_settings->reset("EnableFeralGamemode");
|
m_settings->reset("EnableFeralGamemode");
|
||||||
m_settings->reset("EnableMangoHud");
|
m_settings->reset("EnableMangoHud");
|
||||||
m_settings->reset("UseDiscreteGpu");
|
m_settings->reset("UseDiscreteGpu");
|
||||||
|
m_settings->reset("UseZink");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game time
|
// Game time
|
||||||
@ -358,6 +361,7 @@ void InstanceSettingsPage::loadSettings()
|
|||||||
ui->enableFeralGamemodeCheck->setChecked(m_settings->get("EnableFeralGamemode").toBool());
|
ui->enableFeralGamemodeCheck->setChecked(m_settings->get("EnableFeralGamemode").toBool());
|
||||||
ui->enableMangoHud->setChecked(m_settings->get("EnableMangoHud").toBool());
|
ui->enableMangoHud->setChecked(m_settings->get("EnableMangoHud").toBool());
|
||||||
ui->useDiscreteGpuCheck->setChecked(m_settings->get("UseDiscreteGpu").toBool());
|
ui->useDiscreteGpuCheck->setChecked(m_settings->get("UseDiscreteGpu").toBool());
|
||||||
|
ui->useZink->setChecked(m_settings->get("UseZink").toBool());
|
||||||
|
|
||||||
#if !defined(Q_OS_LINUX)
|
#if !defined(Q_OS_LINUX)
|
||||||
ui->settingsTabs->setTabVisible(ui->settingsTabs->indexOf(ui->performancePage), false);
|
ui->settingsTabs->setTabVisible(ui->settingsTabs->indexOf(ui->performancePage), false);
|
||||||
|
@ -574,6 +574,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="useZink">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Use Zink, a Mesa OpenGL driver that implements OpenGL on top of Vulkan. Performance may vary depending on the situation. Note: If no suitable Vulkan driver is found, software rendering will be used.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use Zink</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -200,7 +200,9 @@ void ImportPage::setExtraInfo(const QMap<QString, QString>& extra_info)
|
|||||||
|
|
||||||
void ImportPage::on_modpackBtn_clicked()
|
void ImportPage::on_modpackBtn_clicked()
|
||||||
{
|
{
|
||||||
auto filter = QMimeDatabase().mimeTypeForName("application/zip").filterString();
|
const QMimeType zip = QMimeDatabase().mimeTypeForName("application/zip");
|
||||||
|
auto filter = tr("Supported files") + QString(" (%1 *.mrpack)").arg(zip.globPatterns().join(" "));
|
||||||
|
filter += ";;" + zip.filterString();
|
||||||
//: Option for filtering for *.mrpack files when importing
|
//: Option for filtering for *.mrpack files when importing
|
||||||
filter += ";;" + tr("Modrinth pack") + " (*.mrpack)";
|
filter += ";;" + tr("Modrinth pack") + " (*.mrpack)";
|
||||||
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter);
|
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter);
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
|
||||||
|
<ws2:longPathAware>true</ws2:longPathAware>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
<assemblyIdentity name="PrismLauncher.Application.1" type="win32" version="@Launcher_VERSION_NAME4@" />
|
<assemblyIdentity name="PrismLauncher.Application.1" type="win32" version="@Launcher_VERSION_NAME4@" />
|
||||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
<security>
|
<security>
|
||||||
|
Loading…
Reference in New Issue
Block a user