mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-09-14 06:25:54 -04:00
Merge branch 'PrismLauncher:develop' into dev
This commit is contained in:
commit
5294479bf2
2
.github/workflows/update-flake.yml
vendored
2
.github/workflows/update-flake.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: cachix/install-nix-action@cebd211ec2008b83bda8fb0b21c3c072f004fe04 # v31
|
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||||
|
|
||||||
- uses: DeterminateSystems/update-flake-lock@v26
|
- uses: DeterminateSystems/update-flake-lock@v26
|
||||||
with:
|
with:
|
||||||
|
@ -166,7 +166,7 @@ class Config {
|
|||||||
QString DISCORD_URL;
|
QString DISCORD_URL;
|
||||||
QString SUBREDDIT_URL;
|
QString SUBREDDIT_URL;
|
||||||
|
|
||||||
QString RESOURCE_BASE = "https://resources.download.minecraft.net/";
|
QString DEFAULT_RESOURCE_BASE = "https://resources.download.minecraft.net/";
|
||||||
QString LIBRARY_BASE = "https://libraries.minecraft.net/";
|
QString LIBRARY_BASE = "https://libraries.minecraft.net/";
|
||||||
QString IMGUR_BASE_URL = "https://api.imgur.com/3/";
|
QString IMGUR_BASE_URL = "https://api.imgur.com/3/";
|
||||||
QString FMLLIBS_BASE_URL;
|
QString FMLLIBS_BASE_URL;
|
||||||
|
6
flake.lock
generated
6
flake.lock
generated
@ -18,11 +18,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1751637120,
|
"lastModified": 1751984180,
|
||||||
"narHash": "sha256-xVNy/XopSfIG9c46nRmPaKfH1Gn/56vQ8++xWA8itO4=",
|
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5c724ed1388e53cc231ed98330a60eb2f7be4be3",
|
"rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -864,6 +864,15 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
|||||||
// get rid of invalid meta urls
|
// get rid of invalid meta urls
|
||||||
if (!metaUrl.isValid() || (metaUrl.scheme() != "http" && metaUrl.scheme() != "https"))
|
if (!metaUrl.isValid() || (metaUrl.scheme() != "http" && metaUrl.scheme() != "https"))
|
||||||
m_settings->reset("MetaURLOverride");
|
m_settings->reset("MetaURLOverride");
|
||||||
|
|
||||||
|
// Resource URL
|
||||||
|
m_settings->registerSetting("ResourceURL", BuildConfig.DEFAULT_RESOURCE_BASE);
|
||||||
|
|
||||||
|
QUrl resourceUrl(m_settings->get("ResourceURL").toString());
|
||||||
|
|
||||||
|
// get rid of invalid resource urls
|
||||||
|
if (!resourceUrl.isValid() || (resourceUrl.scheme() != "http" && resourceUrl.scheme() != "https"))
|
||||||
|
m_settings->reset("ResourceURL");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_settings->registerSetting("CloseAfterLaunch", false);
|
m_settings->registerSetting("CloseAfterLaunch", false);
|
||||||
|
@ -298,7 +298,8 @@ QString AssetObject::getLocalPath()
|
|||||||
|
|
||||||
QUrl AssetObject::getUrl()
|
QUrl AssetObject::getUrl()
|
||||||
{
|
{
|
||||||
return BuildConfig.RESOURCE_BASE + getRelPath();
|
auto resourceURL = APPLICATION->settings()->get("ResourceURL").toString();
|
||||||
|
return resourceURL + getRelPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AssetObject::getRelPath()
|
QString AssetObject::getRelPath()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "AssetUpdateTask.h"
|
#include "AssetUpdateTask.h"
|
||||||
|
|
||||||
|
#include "BuildConfig.h"
|
||||||
#include "launch/LaunchStep.h"
|
#include "launch/LaunchStep.h"
|
||||||
#include "minecraft/AssetsUtils.h"
|
#include "minecraft/AssetsUtils.h"
|
||||||
#include "minecraft/MinecraftInstance.h"
|
#include "minecraft/MinecraftInstance.h"
|
||||||
@ -71,7 +72,12 @@ void AssetUpdateTask::assetIndexFinished()
|
|||||||
|
|
||||||
auto job = index.getDownloadJob();
|
auto job = index.getDownloadJob();
|
||||||
if (job) {
|
if (job) {
|
||||||
setStatus(tr("Getting the assets files from Mojang..."));
|
QString resourceURL = APPLICATION->settings()->get("ResourceURL").toString();
|
||||||
|
QString source = tr("Mojang");
|
||||||
|
if (resourceURL != BuildConfig.DEFAULT_RESOURCE_BASE) {
|
||||||
|
source = QUrl(resourceURL).host();
|
||||||
|
}
|
||||||
|
setStatus(tr("Getting the assets files from %1...").arg(source));
|
||||||
downloadJob = job;
|
downloadJob = job;
|
||||||
connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded);
|
connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded);
|
||||||
connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed);
|
connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed);
|
||||||
|
@ -493,16 +493,35 @@ bool FlameCreationTask::createInstance()
|
|||||||
|
|
||||||
void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
|
void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
|
||||||
{
|
{
|
||||||
auto results = m_modIdResolver->getResults();
|
auto results = m_modIdResolver->getResults().files;
|
||||||
|
|
||||||
|
QStringList optionalFiles;
|
||||||
|
for (auto& result : results) {
|
||||||
|
if (!result.required) {
|
||||||
|
optionalFiles << FS::PathCombine(result.targetFolder, result.version.fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!optionalFiles.empty()) {
|
||||||
|
OptionalModDialog optionalModDialog(m_parent, optionalFiles);
|
||||||
|
if (optionalModDialog.exec() == QDialog::Rejected) {
|
||||||
|
emitAborted();
|
||||||
|
loop.quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_selectedOptionalMods = optionalModDialog.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
// first check for blocked mods
|
// first check for blocked mods
|
||||||
QList<BlockedMod> blocked_mods;
|
QList<BlockedMod> blocked_mods;
|
||||||
auto anyBlocked = false;
|
auto anyBlocked = false;
|
||||||
for (const auto& result : results.files.values()) {
|
for (const auto& result : results.values()) {
|
||||||
if (result.resourceType != PackedResourceType::Mod) {
|
if (result.resourceType != PackedResourceType::Mod) {
|
||||||
m_otherResources.append(std::make_pair(result.version.fileName, result.targetFolder));
|
m_otherResources.append(std::make_pair(result.version.fileName, result.targetFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip optional mods that were not selected
|
||||||
if (result.version.downloadUrl.isEmpty()) {
|
if (result.version.downloadUrl.isEmpty()) {
|
||||||
BlockedMod blocked_mod;
|
BlockedMod blocked_mod;
|
||||||
blocked_mod.name = result.version.fileName;
|
blocked_mod.name = result.version.fileName;
|
||||||
@ -511,6 +530,10 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
|
|||||||
blocked_mod.matched = false;
|
blocked_mod.matched = false;
|
||||||
blocked_mod.localPath = "";
|
blocked_mod.localPath = "";
|
||||||
blocked_mod.targetFolder = result.targetFolder;
|
blocked_mod.targetFolder = result.targetFolder;
|
||||||
|
auto fileName = result.version.fileName;
|
||||||
|
fileName = FS::RemoveInvalidPathChars(fileName);
|
||||||
|
auto relpath = FS::PathCombine(result.targetFolder, fileName);
|
||||||
|
blocked_mod.disabled = !result.required && !m_selectedOptionalMods.contains(relpath);
|
||||||
|
|
||||||
blocked_mods.append(blocked_mod);
|
blocked_mods.append(blocked_mod);
|
||||||
|
|
||||||
@ -546,30 +569,12 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
|
|||||||
m_filesJob.reset(new NetJob(tr("Mod Download Flame"), APPLICATION->network()));
|
m_filesJob.reset(new NetJob(tr("Mod Download Flame"), APPLICATION->network()));
|
||||||
auto results = m_modIdResolver->getResults().files;
|
auto results = m_modIdResolver->getResults().files;
|
||||||
|
|
||||||
QStringList optionalFiles;
|
|
||||||
for (auto& result : results) {
|
|
||||||
if (!result.required) {
|
|
||||||
optionalFiles << FS::PathCombine(result.targetFolder, result.version.fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList selectedOptionalMods;
|
|
||||||
if (!optionalFiles.empty()) {
|
|
||||||
OptionalModDialog optionalModDialog(m_parent, optionalFiles);
|
|
||||||
if (optionalModDialog.exec() == QDialog::Rejected) {
|
|
||||||
emitAborted();
|
|
||||||
loop.quit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedOptionalMods = optionalModDialog.getResult();
|
|
||||||
}
|
|
||||||
for (const auto& result : results) {
|
for (const auto& result : results) {
|
||||||
auto fileName = result.version.fileName;
|
auto fileName = result.version.fileName;
|
||||||
fileName = FS::RemoveInvalidPathChars(fileName);
|
fileName = FS::RemoveInvalidPathChars(fileName);
|
||||||
auto relpath = FS::PathCombine(result.targetFolder, fileName);
|
auto relpath = FS::PathCombine(result.targetFolder, fileName);
|
||||||
|
|
||||||
if (!result.required && !selectedOptionalMods.contains(relpath)) {
|
if (!result.required && !m_selectedOptionalMods.contains(relpath)) {
|
||||||
relpath += ".disabled";
|
relpath += ".disabled";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,6 +622,8 @@ void FlameCreationTask::copyBlockedMods(QList<BlockedMod> const& blocked_mods)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto destPath = FS::PathCombine(m_stagingPath, "minecraft", mod.targetFolder, mod.name);
|
auto destPath = FS::PathCombine(m_stagingPath, "minecraft", mod.targetFolder, mod.name);
|
||||||
|
if (mod.disabled)
|
||||||
|
destPath += ".disabled";
|
||||||
|
|
||||||
setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total)));
|
setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total)));
|
||||||
|
|
||||||
|
@ -92,4 +92,6 @@ class FlameCreationTask final : public InstanceCreationTask {
|
|||||||
QList<std::pair<QString, QString>> m_otherResources;
|
QList<std::pair<QString, QString>> m_otherResources;
|
||||||
|
|
||||||
std::optional<InstancePtr> m_instance;
|
std::optional<InstancePtr> m_instance;
|
||||||
|
|
||||||
|
QStringList m_selectedOptionalMods;
|
||||||
};
|
};
|
||||||
|
@ -42,6 +42,7 @@ struct BlockedMod {
|
|||||||
bool matched;
|
bool matched;
|
||||||
QString localPath;
|
QString localPath;
|
||||||
QString targetFolder;
|
QString targetFolder;
|
||||||
|
bool disabled = false;
|
||||||
bool move = false;
|
bool move = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ APIPage::APIPage(QWidget* parent) : QWidget(parent), ui(new Ui::APIPage)
|
|||||||
updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex());
|
updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex());
|
||||||
// NOTE: this allows http://, but we replace that with https later anyway
|
// NOTE: this allows http://, but we replace that with https later anyway
|
||||||
ui->metaURL->setValidator(new QRegularExpressionValidator(s_validUrlRegExp, ui->metaURL));
|
ui->metaURL->setValidator(new QRegularExpressionValidator(s_validUrlRegExp, ui->metaURL));
|
||||||
|
ui->resourceURL->setValidator(new QRegularExpressionValidator(s_validUrlRegExp, ui->resourceURL));
|
||||||
ui->baseURLEntry->setValidator(new QRegularExpressionValidator(s_validUrlRegExp, ui->baseURLEntry));
|
ui->baseURLEntry->setValidator(new QRegularExpressionValidator(s_validUrlRegExp, ui->baseURLEntry));
|
||||||
ui->msaClientID->setValidator(new QRegularExpressionValidator(s_validMSAClientID, ui->msaClientID));
|
ui->msaClientID->setValidator(new QRegularExpressionValidator(s_validMSAClientID, ui->msaClientID));
|
||||||
ui->flameKey->setValidator(new QRegularExpressionValidator(s_validFlameKey, ui->flameKey));
|
ui->flameKey->setValidator(new QRegularExpressionValidator(s_validFlameKey, ui->flameKey));
|
||||||
@ -137,6 +138,8 @@ void APIPage::loadSettings()
|
|||||||
ui->msaClientID->setText(msaClientID);
|
ui->msaClientID->setText(msaClientID);
|
||||||
QString metaURL = s->get("MetaURLOverride").toString();
|
QString metaURL = s->get("MetaURLOverride").toString();
|
||||||
ui->metaURL->setText(metaURL);
|
ui->metaURL->setText(metaURL);
|
||||||
|
QString resourceURL = s->get("ResourceURL").toString();
|
||||||
|
ui->resourceURL->setText(resourceURL);
|
||||||
QString flameKey = s->get("FlameKeyOverride").toString();
|
QString flameKey = s->get("FlameKeyOverride").toString();
|
||||||
ui->flameKey->setText(flameKey);
|
ui->flameKey->setText(flameKey);
|
||||||
QString modrinthToken = s->get("ModrinthToken").toString();
|
QString modrinthToken = s->get("ModrinthToken").toString();
|
||||||
@ -156,18 +159,31 @@ void APIPage::applySettings()
|
|||||||
QString msaClientID = ui->msaClientID->text();
|
QString msaClientID = ui->msaClientID->text();
|
||||||
s->set("MSAClientIDOverride", msaClientID);
|
s->set("MSAClientIDOverride", msaClientID);
|
||||||
QUrl metaURL(ui->metaURL->text());
|
QUrl metaURL(ui->metaURL->text());
|
||||||
|
QUrl resourceURL(ui->resourceURL->text());
|
||||||
// Add required trailing slash
|
// Add required trailing slash
|
||||||
if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) {
|
if (!metaURL.isEmpty() && !metaURL.path().endsWith('/')) {
|
||||||
QString path = metaURL.path();
|
QString path = metaURL.path();
|
||||||
path.append('/');
|
path.append('/');
|
||||||
metaURL.setPath(path);
|
metaURL.setPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!resourceURL.isEmpty() && !resourceURL.path().endsWith('/')) {
|
||||||
|
QString path = resourceURL.path();
|
||||||
|
path.append('/');
|
||||||
|
resourceURL.setPath(path);
|
||||||
|
}
|
||||||
// Don't allow HTTP, since meta is basically RCE with all the jar files.
|
// Don't allow HTTP, since meta is basically RCE with all the jar files.
|
||||||
if (!metaURL.isEmpty() && metaURL.scheme() == "http") {
|
if (!metaURL.isEmpty() && metaURL.scheme() == "http") {
|
||||||
metaURL.setScheme("https");
|
metaURL.setScheme("https");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also don't allow HTTP
|
||||||
|
if (!resourceURL.isEmpty() && resourceURL.scheme() == "http") {
|
||||||
|
resourceURL.setScheme("https");
|
||||||
|
}
|
||||||
|
|
||||||
s->set("MetaURLOverride", metaURL.toString());
|
s->set("MetaURLOverride", metaURL.toString());
|
||||||
|
s->set("ResourceURL", resourceURL.toString());
|
||||||
QString flameKey = ui->flameKey->text();
|
QString flameKey = ui->flameKey->text();
|
||||||
s->set("FlameKeyOverride", flameKey);
|
s->set("FlameKeyOverride", flameKey);
|
||||||
QString modrinthToken = ui->modrinthToken->text();
|
QString modrinthToken = ui->modrinthToken->text();
|
||||||
|
@ -129,6 +129,38 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_assets">
|
||||||
|
<property name="title">
|
||||||
|
<string>Assets Server</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>You can set this to another server if you have problems with downloading assets.</string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="resourceURL">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Use Default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_ua">
|
<widget class="QGroupBox" name="groupBox_ua">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user