Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feature/java-downloader
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
commit
b5bbe93775
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -79,7 +79,7 @@ jobs:
|
||||
qt_ver: 6
|
||||
qt_host: windows
|
||||
qt_arch: ""
|
||||
qt_version: "6.7.1"
|
||||
qt_version: "6.7.2"
|
||||
qt_modules: "qt5compat qtimageformats qtnetworkauth"
|
||||
|
||||
- os: windows-2022
|
||||
@ -90,7 +90,7 @@ jobs:
|
||||
qt_ver: 6
|
||||
qt_host: windows
|
||||
qt_arch: "win64_msvc2019_arm64"
|
||||
qt_version: "6.7.1"
|
||||
qt_version: "6.7.2"
|
||||
qt_modules: "qt5compat qtimageformats qtnetworkauth"
|
||||
|
||||
- os: macos-12
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
qt_ver: 6
|
||||
qt_host: mac
|
||||
qt_arch: ""
|
||||
qt_version: "6.7.1"
|
||||
qt_version: "6.7.2"
|
||||
qt_modules: "qt5compat qtimageformats qtnetworkauth"
|
||||
|
||||
- os: macos-12
|
||||
@ -160,7 +160,7 @@ jobs:
|
||||
|
||||
- name: Setup ccache
|
||||
if: (runner.os != 'Windows' || matrix.msystem == '') && inputs.build_type == 'Debug'
|
||||
uses: hendrikmuhs/ccache-action@v1.2.13
|
||||
uses: hendrikmuhs/ccache-action@v1.2.14
|
||||
with:
|
||||
key: ${{ matrix.os }}-qt${{ matrix.qt_ver }}-${{ matrix.architecture }}
|
||||
|
||||
|
2
.github/workflows/update-flake.yml
vendored
2
.github/workflows/update-flake.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
|
||||
|
||||
- uses: DeterminateSystems/update-flake-lock@v22
|
||||
- uses: DeterminateSystems/update-flake-lock@v23
|
||||
with:
|
||||
commit-msg: "chore(nix): update lockfile"
|
||||
pr-title: "chore(nix): update lockfile"
|
||||
|
3
BUILD.md
3
BUILD.md
@ -1,3 +0,0 @@
|
||||
# Build Instructions
|
||||
|
||||
Full build instructions are available on [the website](https://prismlauncher.org/wiki/development/build-instructions/).
|
@ -61,7 +61,12 @@ The translation effort for Prism Launcher is hosted on [Weblate](https://hosted.
|
||||
|
||||
## Building
|
||||
|
||||
If you want to build Prism Launcher yourself, check the [Build Instructions](https://prismlauncher.org/wiki/development/build-instructions/).
|
||||
If you want to build Prism Launcher yourself, check the build instructions:
|
||||
|
||||
- [Windows](https://prismlauncher.org/wiki/development/build-instructions/windows/)
|
||||
- [Linux](https://prismlauncher.org/wiki/development/build-instructions/linux/)
|
||||
- [MacOS](https://prismlauncher.org/wiki/development/build-instructions/macos/)
|
||||
- [OpenBSD](https://prismlauncher.org/wiki/development/build-instructions/openbsd/)
|
||||
|
||||
## Sponsors & Partners
|
||||
|
||||
|
18
flake.lock
generated
18
flake.lock
generated
@ -23,11 +23,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719994518,
|
||||
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
|
||||
"lastModified": 1722555600,
|
||||
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
|
||||
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -75,11 +75,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1720768451,
|
||||
"narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=",
|
||||
"lastModified": 1723175592,
|
||||
"narHash": "sha256-M0xJ3FbDUc4fRZ84dPGx5VvgFsOzds77KiBMW/mMTnI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9",
|
||||
"rev": "5e0ca22929f3342b19569b21b2f3462f053e497b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -103,11 +103,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720524665,
|
||||
"narHash": "sha256-ni/87oHPZm6Gv0ECYxr1f6uxB0UKBWJ6HvS7lwLU6oY=",
|
||||
"lastModified": 1723202784,
|
||||
"narHash": "sha256-qbhjc/NEGaDbyy0ucycubq4N3//gDFFH3DOmp1D3u1Q=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "8d6a17d0cdf411c55f12602624df6368ad86fac1",
|
||||
"rev": "c7012d0c18567c889b948781bc74a501e92275d1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -238,6 +238,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
{ { { "d", "dir" }, "Use a custom path as application root (use '.' for current directory)", "directory" },
|
||||
{ { "l", "launch" }, "Launch the specified instance (by instance ID)", "instance" },
|
||||
{ { "s", "server" }, "Join the specified server on launch (only valid in combination with --launch)", "address" },
|
||||
{ { "w", "world" }, "Join the specified world on launch (only valid in combination with --launch)", "world" },
|
||||
{ { "a", "profile" }, "Use the account specified by its profile name (only valid in combination with --launch)", "profile" },
|
||||
{ "alive", "Write a small '" + liveCheckFile + "' file after the launcher starts" },
|
||||
{ { "I", "import" }, "Import instance or resource from specified local path or URL", "url" },
|
||||
@ -252,6 +253,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
|
||||
m_instanceIdToLaunch = parser.value("launch");
|
||||
m_serverToJoin = parser.value("server");
|
||||
m_worldToJoin = parser.value("world");
|
||||
m_profileToUse = parser.value("profile");
|
||||
m_liveCheck = parser.isSet("alive");
|
||||
|
||||
@ -267,7 +269,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
}
|
||||
|
||||
// error if --launch is missing with --server or --profile
|
||||
if ((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) {
|
||||
if (((!m_serverToJoin.isEmpty() || !m_worldToJoin.isEmpty()) || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) {
|
||||
std::cerr << "--server and --profile can only be used in combination with --launch!" << std::endl;
|
||||
m_status = Application::Failed;
|
||||
return;
|
||||
@ -387,6 +389,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
|
||||
if (!m_serverToJoin.isEmpty()) {
|
||||
launch.args["server"] = m_serverToJoin;
|
||||
} else if (!m_worldToJoin.isEmpty()) {
|
||||
launch.args["world"] = m_worldToJoin;
|
||||
}
|
||||
if (!m_profileToUse.isEmpty()) {
|
||||
launch.args["profile"] = m_profileToUse;
|
||||
@ -525,6 +529,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
}
|
||||
if (!m_serverToJoin.isEmpty()) {
|
||||
qDebug() << "Address of server to join :" << m_serverToJoin;
|
||||
} else if (!m_worldToJoin.isEmpty()) {
|
||||
qDebug() << "Name of the world to join :" << m_worldToJoin;
|
||||
}
|
||||
qDebug() << "<> Paths set.";
|
||||
}
|
||||
@ -1163,14 +1169,17 @@ void Application::performMainStartupAction()
|
||||
if (!m_instanceIdToLaunch.isEmpty()) {
|
||||
auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
|
||||
if (inst) {
|
||||
MinecraftServerTargetPtr serverToJoin = nullptr;
|
||||
MinecraftTarget::Ptr targetToJoin = nullptr;
|
||||
MinecraftAccountPtr accountToUse = nullptr;
|
||||
|
||||
qDebug() << "<> Instance" << m_instanceIdToLaunch << "launching";
|
||||
if (!m_serverToJoin.isEmpty()) {
|
||||
// FIXME: validate the server string
|
||||
serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(m_serverToJoin)));
|
||||
targetToJoin.reset(new MinecraftTarget(MinecraftTarget::parse(m_serverToJoin, false)));
|
||||
qDebug() << " Launching with server" << m_serverToJoin;
|
||||
} else if (!m_worldToJoin.isEmpty()) {
|
||||
targetToJoin.reset(new MinecraftTarget(MinecraftTarget::parse(m_worldToJoin, true)));
|
||||
qDebug() << " Launching with world" << m_worldToJoin;
|
||||
}
|
||||
|
||||
if (!m_profileToUse.isEmpty()) {
|
||||
@ -1181,7 +1190,7 @@ void Application::performMainStartupAction()
|
||||
qDebug() << " Launching with account" << m_profileToUse;
|
||||
}
|
||||
|
||||
launch(inst, true, false, serverToJoin, accountToUse);
|
||||
launch(inst, true, false, targetToJoin, accountToUse);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1271,6 +1280,7 @@ void Application::messageReceived(const QByteArray& message)
|
||||
} else if (command == "launch") {
|
||||
QString id = received.args["id"];
|
||||
QString server = received.args["server"];
|
||||
QString world = received.args["world"];
|
||||
QString profile = received.args["profile"];
|
||||
|
||||
InstancePtr instance;
|
||||
@ -1285,11 +1295,12 @@ void Application::messageReceived(const QByteArray& message)
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftServerTargetPtr serverObject = nullptr;
|
||||
MinecraftTarget::Ptr serverObject = nullptr;
|
||||
if (!server.isEmpty()) {
|
||||
serverObject = std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(server));
|
||||
serverObject = std::make_shared<MinecraftTarget>(MinecraftTarget::parse(server, false));
|
||||
} else if (!world.isEmpty()) {
|
||||
serverObject = std::make_shared<MinecraftTarget>(MinecraftTarget::parse(world, true));
|
||||
}
|
||||
|
||||
MinecraftAccountPtr accountObject;
|
||||
if (!profile.isEmpty()) {
|
||||
accountObject = accounts()->getAccountByProfileName(profile);
|
||||
@ -1338,11 +1349,7 @@ bool Application::openJsonEditor(const QString& filename)
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::launch(InstancePtr instance,
|
||||
bool online,
|
||||
bool demo,
|
||||
MinecraftServerTargetPtr serverToJoin,
|
||||
MinecraftAccountPtr accountToUse)
|
||||
bool Application::launch(InstancePtr instance, bool online, bool demo, MinecraftTarget::Ptr targetToJoin, MinecraftAccountPtr accountToUse)
|
||||
{
|
||||
if (m_updateRunning) {
|
||||
qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed.";
|
||||
@ -1360,7 +1367,7 @@ bool Application::launch(InstancePtr instance,
|
||||
controller->setOnline(online);
|
||||
controller->setDemo(demo);
|
||||
controller->setProfiler(profilers().value(instance->settings()->get("Profiler").toString(), nullptr).get());
|
||||
controller->setServerToJoin(serverToJoin);
|
||||
controller->setTargetToJoin(targetToJoin);
|
||||
controller->setAccountToUse(accountToUse);
|
||||
if (window) {
|
||||
controller->setParentWidget(window);
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
#include <BaseInstance.h>
|
||||
|
||||
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
|
||||
class LaunchController;
|
||||
class LocalPeer;
|
||||
@ -203,7 +203,7 @@ class Application : public QApplication {
|
||||
bool launch(InstancePtr instance,
|
||||
bool online = true,
|
||||
bool demo = false,
|
||||
MinecraftServerTargetPtr serverToJoin = nullptr,
|
||||
MinecraftTarget::Ptr targetToJoin = nullptr,
|
||||
MinecraftAccountPtr accountToUse = nullptr);
|
||||
bool kill(InstancePtr instance);
|
||||
void closeCurrentWindow();
|
||||
@ -291,6 +291,7 @@ class Application : public QApplication {
|
||||
QString m_detectedOpenALPath;
|
||||
QString m_instanceIdToLaunch;
|
||||
QString m_serverToJoin;
|
||||
QString m_worldToJoin;
|
||||
QString m_profileToUse;
|
||||
bool m_liveCheck = false;
|
||||
QList<QUrl> m_urlsToImport;
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "net/Mode.h"
|
||||
|
||||
#include "RuntimeContext.h"
|
||||
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
|
||||
class QDir;
|
||||
class Task;
|
||||
@ -184,7 +184,7 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
|
||||
virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0;
|
||||
|
||||
/// returns a valid launcher (task container)
|
||||
virtual shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) = 0;
|
||||
virtual shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftTarget::Ptr targetToJoin) = 0;
|
||||
|
||||
/// returns the current launch task (if any)
|
||||
shared_qobject_ptr<LaunchTask> getLaunchTask();
|
||||
@ -256,7 +256,7 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
|
||||
/**
|
||||
* 'print' a verbose description of the instance into a QStringList
|
||||
*/
|
||||
virtual QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) = 0;
|
||||
virtual QStringList verboseDescription(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin) = 0;
|
||||
|
||||
Status currentStatus() const;
|
||||
|
||||
|
@ -140,7 +140,6 @@ set(NET_SOURCES
|
||||
net/HeaderProxy.h
|
||||
net/RawHeaderProxy.h
|
||||
net/ApiHeaderProxy.h
|
||||
net/StaticHeaderProxy.h
|
||||
net/ApiDownload.h
|
||||
net/ApiDownload.cpp
|
||||
net/ApiUpload.cpp
|
||||
@ -265,8 +264,8 @@ set(MINECRAFT_SOURCES
|
||||
minecraft/launch/ExtractNatives.h
|
||||
minecraft/launch/LauncherPartLaunch.cpp
|
||||
minecraft/launch/LauncherPartLaunch.h
|
||||
minecraft/launch/MinecraftServerTarget.cpp
|
||||
minecraft/launch/MinecraftServerTarget.h
|
||||
minecraft/launch/MinecraftTarget.cpp
|
||||
minecraft/launch/MinecraftTarget.h
|
||||
minecraft/launch/PrintInstanceInfo.cpp
|
||||
minecraft/launch/PrintInstanceInfo.h
|
||||
minecraft/launch/ReconstructAssets.cpp
|
||||
|
@ -72,7 +72,7 @@ void appendSafe(const QString& filename, const QByteArray& data);
|
||||
void append(const QString& filename, const QByteArray& data);
|
||||
|
||||
/**
|
||||
* read data from a file safely\
|
||||
* read data from a file safely
|
||||
*/
|
||||
QByteArray read(const QString& filename);
|
||||
|
||||
|
@ -22,7 +22,7 @@ class InstancePageProvider : protected QObject, public BasePageProvider {
|
||||
public:
|
||||
explicit InstancePageProvider(InstancePtr parent) { inst = parent; }
|
||||
|
||||
virtual ~InstancePageProvider() {};
|
||||
virtual ~InstancePageProvider() = default;
|
||||
virtual QList<BasePage*> getPages() override
|
||||
{
|
||||
QList<BasePage*> values;
|
||||
@ -39,7 +39,7 @@ class InstancePageProvider : protected QObject, public BasePageProvider {
|
||||
values.append(new TexturePackPage(onesix.get(), onesix->texturePackList()));
|
||||
values.append(new ShaderPackPage(onesix.get(), onesix->shaderPackList()));
|
||||
values.append(new NotesPage(onesix.get()));
|
||||
values.append(new WorldListPage(onesix.get(), onesix->worldList()));
|
||||
values.append(new WorldListPage(onesix, onesix->worldList()));
|
||||
values.append(new ServersPage(onesix));
|
||||
// values.append(new GameOptionsPage(onesix.get()));
|
||||
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
|
||||
|
@ -324,7 +324,7 @@ void LaunchController::launchInstance()
|
||||
return;
|
||||
}
|
||||
|
||||
m_launcher = m_instance->createLaunchTask(m_session, m_serverToJoin);
|
||||
m_launcher = m_instance->createLaunchTask(m_session, m_targetToJoin);
|
||||
if (!m_launcher) {
|
||||
emitFailed(tr("Couldn't instantiate a launcher."));
|
||||
return;
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "minecraft/auth/MinecraftAccount.h"
|
||||
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
|
||||
class InstanceWindow;
|
||||
class LaunchController : public Task {
|
||||
@ -48,7 +48,7 @@ class LaunchController : public Task {
|
||||
void executeTask() override;
|
||||
|
||||
LaunchController(QObject* parent = nullptr);
|
||||
virtual ~LaunchController() {};
|
||||
virtual ~LaunchController() = default;
|
||||
|
||||
void setInstance(InstancePtr instance) { m_instance = instance; }
|
||||
|
||||
@ -62,7 +62,7 @@ class LaunchController : public Task {
|
||||
|
||||
void setParentWidget(QWidget* widget) { m_parentWidget = widget; }
|
||||
|
||||
void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { m_serverToJoin = std::move(serverToJoin); }
|
||||
void setTargetToJoin(MinecraftTarget::Ptr targetToJoin) { m_targetToJoin = std::move(targetToJoin); }
|
||||
|
||||
void setAccountToUse(MinecraftAccountPtr accountToUse) { m_accountToUse = std::move(accountToUse); }
|
||||
|
||||
@ -94,5 +94,5 @@ class LaunchController : public Task {
|
||||
MinecraftAccountPtr m_accountToUse = nullptr;
|
||||
AuthSessionPtr m_session;
|
||||
shared_qobject_ptr<LaunchTask> m_launcher;
|
||||
MinecraftServerTargetPtr m_serverToJoin;
|
||||
MinecraftTarget::Ptr m_targetToJoin;
|
||||
};
|
||||
|
@ -344,6 +344,17 @@ std::optional<QStringList> extractSubDir(QuaZip* zip, const QString& subdir, con
|
||||
qWarning() << (QObject::tr("Could not fix permissions for %1").arg(target_file_path));
|
||||
}
|
||||
}
|
||||
} else if (fileInfo.isDir()) {
|
||||
// Ensure the folder has the minimal required permissions
|
||||
QFile::Permissions minimalPermissions = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadGroup |
|
||||
QFile::ExeGroup | QFile::ReadOther | QFile::ExeOther;
|
||||
|
||||
QFile::Permissions currentPermissions = fileInfo.permissions();
|
||||
if ((currentPermissions & minimalPermissions) != minimalPermissions) {
|
||||
if (!QFile::setPermissions(target_file_path, minimalPermissions)) {
|
||||
qWarning() << (QObject::tr("Could not fix permissions for %1").arg(target_file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path;
|
||||
} while (zip->goToNextFile());
|
||||
@ -564,7 +575,7 @@ auto ExtractZipTask::extractZip() -> ZipResult
|
||||
if (!file_name.startsWith(m_subdirectory))
|
||||
continue;
|
||||
|
||||
auto relative_file_name = QDir::fromNativeSeparators(file_name.remove(0, m_subdirectory.size()));
|
||||
auto relative_file_name = QDir::fromNativeSeparators(file_name.mid(m_subdirectory.size()));
|
||||
auto original_name = relative_file_name;
|
||||
setStatus("Unziping: " + relative_file_name);
|
||||
|
||||
@ -614,6 +625,17 @@ auto ExtractZipTask::extractZip() -> ZipResult
|
||||
logWarning(tr("Could not fix permissions for %1").arg(target_file_path));
|
||||
}
|
||||
}
|
||||
} else if (fileInfo.isDir()) {
|
||||
// Ensure the folder has the minimal required permissions
|
||||
QFile::Permissions minimalPermissions = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadGroup |
|
||||
QFile::ExeGroup | QFile::ReadOther | QFile::ExeOther;
|
||||
|
||||
QFile::Permissions currentPermissions = fileInfo.permissions();
|
||||
if ((currentPermissions & minimalPermissions) != minimalPermissions) {
|
||||
if (!QFile::setPermissions(target_file_path, minimalPermissions)) {
|
||||
logWarning(tr("Could not fix permissions for %1").arg(target_file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path;
|
||||
|
@ -40,8 +40,8 @@ namespace MangoHud {
|
||||
|
||||
QString getLibraryString()
|
||||
{
|
||||
/*
|
||||
* Check for vulkan layers in this order:
|
||||
/**
|
||||
* Guess MangoHud install location by searching for vulkan layers in this order:
|
||||
*
|
||||
* $VK_LAYER_PATH
|
||||
* $XDG_DATA_DIRS (/usr/local/share/:/usr/share/)
|
||||
@ -49,8 +49,9 @@ QString getLibraryString()
|
||||
* /etc
|
||||
* $XDG_CONFIG_DIRS (/etc/xdg)
|
||||
* $XDG_CONFIG_HOME (~/.config)
|
||||
*
|
||||
* @returns Absolute path of libMangoHud.so if found and empty QString otherwise.
|
||||
*/
|
||||
|
||||
QStringList vkLayerList;
|
||||
{
|
||||
QString home = QDir::homePath();
|
||||
@ -85,7 +86,7 @@ QString getLibraryString()
|
||||
vkLayerList << FS::PathCombine(xdgConfigHome, "vulkan", "implicit_layer.d");
|
||||
}
|
||||
|
||||
for (QString vkLayer : vkLayerList) {
|
||||
for (const QString& vkLayer : vkLayerList) {
|
||||
// prefer to use architecture specific vulkan layers
|
||||
QString currentArch = QSysInfo::currentCpuArchitecture();
|
||||
|
||||
@ -95,8 +96,8 @@ QString getLibraryString()
|
||||
|
||||
QStringList manifestNames = { QString("MangoHud.%1.json").arg(currentArch), "MangoHud.json" };
|
||||
|
||||
QString filePath = "";
|
||||
for (QString manifestName : manifestNames) {
|
||||
QString filePath{};
|
||||
for (const QString& manifestName : manifestNames) {
|
||||
QString tryPath = FS::PathCombine(vkLayer, manifestName);
|
||||
if (QFile::exists(tryPath)) {
|
||||
filePath = tryPath;
|
||||
@ -111,10 +112,23 @@ QString getLibraryString()
|
||||
auto conf = Json::requireDocument(filePath, vkLayer);
|
||||
auto confObject = Json::requireObject(conf, vkLayer);
|
||||
auto layer = Json::ensureObject(confObject, "layer");
|
||||
return Json::ensureString(layer, "library_path");
|
||||
QString libraryName = Json::ensureString(layer, "library_path");
|
||||
|
||||
#ifdef __GLIBC__
|
||||
// Check whether mangohud is usable on a glibc based system
|
||||
if (!libraryName.isEmpty()) {
|
||||
QString libraryPath = findLibrary(libraryName);
|
||||
if (!libraryPath.isEmpty()) {
|
||||
return libraryPath;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Without glibc return recorded shared library as-is.
|
||||
return libraryName;
|
||||
#endif
|
||||
}
|
||||
|
||||
return QString();
|
||||
return {};
|
||||
}
|
||||
|
||||
QString findLibrary(QString libName)
|
||||
|
@ -46,13 +46,13 @@ class NullInstance : public BaseInstance {
|
||||
{
|
||||
setVersionBroken(true);
|
||||
}
|
||||
virtual ~NullInstance() {};
|
||||
virtual ~NullInstance() = default;
|
||||
void saveNow() override {}
|
||||
void loadSpecificSettings() override { setSpecificSettingsLoaded(true); }
|
||||
QString getStatusbarDescription() override { return tr("Unknown instance type"); };
|
||||
QSet<QString> traits() const override { return {}; };
|
||||
QString instanceConfigFolder() const override { return instanceRoot(); };
|
||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftServerTargetPtr) override { return nullptr; }
|
||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr, MinecraftTarget::Ptr) override { return nullptr; }
|
||||
shared_qobject_ptr<Task> createUpdateTask([[maybe_unused]] Net::Mode mode) override { return nullptr; }
|
||||
QProcessEnvironment createEnvironment() override { return QProcessEnvironment(); }
|
||||
QProcessEnvironment createLaunchEnvironment() override { return QProcessEnvironment(); }
|
||||
@ -64,7 +64,7 @@ class NullInstance : public BaseInstance {
|
||||
bool canEdit() const override { return false; }
|
||||
bool canLaunch() const override { return false; }
|
||||
void populateLaunchMenu(QMenu* menu) override {}
|
||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override
|
||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin) override
|
||||
{
|
||||
QStringList out;
|
||||
out << "Null instance - placeholder.";
|
||||
|
@ -182,56 +182,58 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString
|
||||
else if (keyType == KEY_WOW64_32KEY)
|
||||
archType = "32";
|
||||
|
||||
HKEY jreKey;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.toStdWString().c_str(), 0, KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) ==
|
||||
ERROR_SUCCESS) {
|
||||
// Read the current type version from the registry.
|
||||
// This will be used to find any key that contains the JavaHome value.
|
||||
for (HKEY baseRegistry : { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }) {
|
||||
HKEY jreKey;
|
||||
if (RegOpenKeyExW(baseRegistry, keyName.toStdWString().c_str(), 0, KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) ==
|
||||
ERROR_SUCCESS) {
|
||||
// Read the current type version from the registry.
|
||||
// This will be used to find any key that contains the JavaHome value.
|
||||
|
||||
WCHAR subKeyName[255];
|
||||
DWORD subKeyNameSize, numSubKeys, retCode;
|
||||
WCHAR subKeyName[255];
|
||||
DWORD subKeyNameSize, numSubKeys, retCode;
|
||||
|
||||
// Get the number of subkeys
|
||||
RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
// Get the number of subkeys
|
||||
RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
// Iterate until RegEnumKeyEx fails
|
||||
if (numSubKeys > 0) {
|
||||
for (DWORD i = 0; i < numSubKeys; i++) {
|
||||
subKeyNameSize = 255;
|
||||
retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, NULL);
|
||||
QString newSubkeyName = QString::fromWCharArray(subKeyName);
|
||||
if (retCode == ERROR_SUCCESS) {
|
||||
// Now open the registry key for the version that we just got.
|
||||
QString newKeyName = keyName + "\\" + newSubkeyName + subkeySuffix;
|
||||
// Iterate until RegEnumKeyEx fails
|
||||
if (numSubKeys > 0) {
|
||||
for (DWORD i = 0; i < numSubKeys; i++) {
|
||||
subKeyNameSize = 255;
|
||||
retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, NULL);
|
||||
QString newSubkeyName = QString::fromWCharArray(subKeyName);
|
||||
if (retCode == ERROR_SUCCESS) {
|
||||
// Now open the registry key for the version that we just got.
|
||||
QString newKeyName = keyName + "\\" + newSubkeyName + subkeySuffix;
|
||||
|
||||
HKEY newKey;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, newKeyName.toStdWString().c_str(), 0, KEY_READ | keyType, &newKey) ==
|
||||
ERROR_SUCCESS) {
|
||||
// Read the JavaHome value to find where Java is installed.
|
||||
DWORD valueSz = 0;
|
||||
if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, &valueSz) == ERROR_SUCCESS) {
|
||||
WCHAR* value = new WCHAR[valueSz];
|
||||
RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE*)value, &valueSz);
|
||||
HKEY newKey;
|
||||
if (RegOpenKeyExW(baseRegistry, newKeyName.toStdWString().c_str(), 0, KEY_READ | keyType, &newKey) ==
|
||||
ERROR_SUCCESS) {
|
||||
// Read the JavaHome value to find where Java is installed.
|
||||
DWORD valueSz = 0;
|
||||
if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, &valueSz) == ERROR_SUCCESS) {
|
||||
WCHAR* value = new WCHAR[valueSz];
|
||||
RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE*)value, &valueSz);
|
||||
|
||||
QString newValue = QString::fromWCharArray(value);
|
||||
delete[] value;
|
||||
QString newValue = QString::fromWCharArray(value);
|
||||
delete[] value;
|
||||
|
||||
// Now, we construct the version object and add it to the list.
|
||||
JavaInstallPtr javaVersion(new JavaInstall());
|
||||
// Now, we construct the version object and add it to the list.
|
||||
JavaInstallPtr javaVersion(new JavaInstall());
|
||||
|
||||
javaVersion->id = newSubkeyName;
|
||||
javaVersion->arch = archType;
|
||||
javaVersion->path = QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe");
|
||||
javas.append(javaVersion);
|
||||
javaVersion->id = newSubkeyName;
|
||||
javaVersion->arch = archType;
|
||||
javaVersion->path = QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe");
|
||||
javas.append(javaVersion);
|
||||
}
|
||||
|
||||
RegCloseKey(newKey);
|
||||
}
|
||||
|
||||
RegCloseKey(newKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(jreKey);
|
||||
RegCloseKey(jreKey);
|
||||
}
|
||||
}
|
||||
|
||||
return javas;
|
||||
|
@ -30,7 +30,7 @@ void LookupServerAddress::setLookupAddress(const QString& lookupAddress)
|
||||
m_dnsLookup->setName(QString("_minecraft._tcp.%1").arg(lookupAddress));
|
||||
}
|
||||
|
||||
void LookupServerAddress::setOutputAddressPtr(MinecraftServerTargetPtr output)
|
||||
void LookupServerAddress::setOutputAddressPtr(MinecraftTarget::Ptr output)
|
||||
{
|
||||
m_output = std::move(output);
|
||||
}
|
||||
|
@ -19,20 +19,20 @@
|
||||
#include <launch/LaunchStep.h>
|
||||
#include <QDnsLookup>
|
||||
|
||||
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
|
||||
class LookupServerAddress : public LaunchStep {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LookupServerAddress(LaunchTask* parent);
|
||||
virtual ~LookupServerAddress() {};
|
||||
virtual ~LookupServerAddress() = default;
|
||||
|
||||
virtual void executeTask();
|
||||
virtual bool abort();
|
||||
virtual bool canAbort() const { return true; }
|
||||
|
||||
void setLookupAddress(const QString& lookupAddress);
|
||||
void setOutputAddressPtr(MinecraftServerTargetPtr output);
|
||||
void setOutputAddressPtr(MinecraftTarget::Ptr output);
|
||||
|
||||
private slots:
|
||||
void on_dnsLookupFinished();
|
||||
@ -42,5 +42,5 @@ class LookupServerAddress : public LaunchStep {
|
||||
|
||||
QDnsLookup* m_dnsLookup;
|
||||
QString m_lookupAddress;
|
||||
MinecraftServerTargetPtr m_output;
|
||||
MinecraftTarget::Ptr m_output;
|
||||
};
|
||||
|
@ -193,8 +193,9 @@ void MinecraftInstance::loadSpecificSettings()
|
||||
}
|
||||
|
||||
// Join server on launch, this does not have a global override
|
||||
m_settings->registerSetting("JoinServerOnLaunch", false);
|
||||
m_settings->registerSetting({ "JoinServerOnLaunch", "JoinOnLaunch" }, false);
|
||||
m_settings->registerSetting("JoinServerOnLaunchAddress", "");
|
||||
m_settings->registerSetting("JoinWorldOnLaunch", "");
|
||||
|
||||
// Use account for instance, this does not have a global override
|
||||
m_settings->registerSetting("UseAccountForInstance", false);
|
||||
@ -520,8 +521,7 @@ QStringList MinecraftInstance::javaArguments()
|
||||
|
||||
if (javaVersion.isModular() && shouldApplyOnlineFixes())
|
||||
// allow reflective access to java.net - required by the skin fix
|
||||
args << "--add-opens"
|
||||
<< "java.base/java.net=ALL-UNNAMED";
|
||||
args << "--add-opens" << "java.base/java.net=ALL-UNNAMED";
|
||||
|
||||
return args;
|
||||
}
|
||||
@ -605,7 +605,7 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment()
|
||||
// dlsym variant is only needed for OpenGL and not included in the vulkan layer
|
||||
appendLib("libMangoHud_dlsym.so");
|
||||
appendLib("libMangoHud_opengl.so");
|
||||
appendLib(mangoHudLib.fileName());
|
||||
preloadList << mangoHudLibString;
|
||||
}
|
||||
|
||||
env.insert("LD_PRELOAD", preloadList.join(QLatin1String(":")));
|
||||
@ -653,7 +653,7 @@ static QString replaceTokensIn(QString text, QMap<QString, QString> with)
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) const
|
||||
QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin) const
|
||||
{
|
||||
auto profile = m_components->getProfile();
|
||||
QString args_pattern = profile->getMinecraftArguments();
|
||||
@ -661,12 +661,16 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, Mine
|
||||
args_pattern += " --tweakClass " + tweaker;
|
||||
}
|
||||
|
||||
if (serverToJoin && !serverToJoin->address.isEmpty()) {
|
||||
if (profile->hasTrait("feature:is_quick_play_multiplayer")) {
|
||||
args_pattern += " --quickPlayMultiplayer " + serverToJoin->address + ':' + QString::number(serverToJoin->port);
|
||||
} else {
|
||||
args_pattern += " --server " + serverToJoin->address;
|
||||
args_pattern += " --port " + QString::number(serverToJoin->port);
|
||||
if (targetToJoin) {
|
||||
if (!targetToJoin->address.isEmpty()) {
|
||||
if (profile->hasTrait("feature:is_quick_play_multiplayer")) {
|
||||
args_pattern += " --quickPlayMultiplayer " + targetToJoin->address + ':' + QString::number(targetToJoin->port);
|
||||
} else {
|
||||
args_pattern += " --server " + targetToJoin->address;
|
||||
args_pattern += " --port " + QString::number(targetToJoin->port);
|
||||
}
|
||||
} else if (!targetToJoin->world.isEmpty() && profile->hasTrait("feature:is_quick_play_singleplayer")) {
|
||||
args_pattern += " --quickPlaySingleplayer " + targetToJoin->world;
|
||||
}
|
||||
}
|
||||
|
||||
@ -710,7 +714,7 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, Mine
|
||||
return parts;
|
||||
}
|
||||
|
||||
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin)
|
||||
{
|
||||
QString launchScript;
|
||||
|
||||
@ -729,9 +733,13 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
|
||||
launchScript += "appletClass " + appletClass + "\n";
|
||||
}
|
||||
|
||||
if (serverToJoin && !serverToJoin->address.isEmpty()) {
|
||||
launchScript += "serverAddress " + serverToJoin->address + "\n";
|
||||
launchScript += "serverPort " + QString::number(serverToJoin->port) + "\n";
|
||||
if (targetToJoin) {
|
||||
if (!targetToJoin->address.isEmpty()) {
|
||||
launchScript += "serverAddress " + targetToJoin->address + "\n";
|
||||
launchScript += "serverPort " + QString::number(targetToJoin->port) + "\n";
|
||||
} else if (!targetToJoin->world.isEmpty()) {
|
||||
launchScript += "worldName " + targetToJoin->world + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// generic minecraft params
|
||||
@ -784,16 +792,15 @@ QString MinecraftInstance::createLaunchScript(AuthSessionPtr session, MinecraftS
|
||||
return launchScript;
|
||||
}
|
||||
|
||||
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin)
|
||||
{
|
||||
QStringList out;
|
||||
out << "Main Class:"
|
||||
<< " " + getMainClass() << "";
|
||||
out << "Native path:"
|
||||
<< " " + getNativePath() << "";
|
||||
out << "Main Class:" << " " + getMainClass() << "";
|
||||
out << "Native path:" << " " + getNativePath() << "";
|
||||
|
||||
auto profile = m_components->getProfile();
|
||||
|
||||
// traits
|
||||
auto alltraits = traits();
|
||||
if (alltraits.size()) {
|
||||
out << "Traits:";
|
||||
@ -803,6 +810,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
||||
out << "";
|
||||
}
|
||||
|
||||
// native libraries
|
||||
auto settings = this->settings();
|
||||
bool nativeOpenAL = settings->get("UseNativeOpenAL").toBool();
|
||||
bool nativeGLFW = settings->get("UseNativeGLFW").toBool();
|
||||
@ -838,6 +846,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
||||
out << "";
|
||||
}
|
||||
|
||||
// mods and core mods
|
||||
auto printModList = [&](const QString& label, ModFolderModel& model) {
|
||||
if (model.size()) {
|
||||
out << QString("%1:").arg(label);
|
||||
@ -866,6 +875,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
||||
printModList("Mods", *(loaderModList().get()));
|
||||
printModList("Core Mods", *(coreModList().get()));
|
||||
|
||||
// jar mods
|
||||
auto& jarMods = profile->getJarMods();
|
||||
if (jarMods.size()) {
|
||||
out << "Jar Mods:";
|
||||
@ -881,11 +891,13 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
||||
out << "";
|
||||
}
|
||||
|
||||
auto params = processMinecraftArgs(nullptr, serverToJoin);
|
||||
// minecraft arguments
|
||||
auto params = processMinecraftArgs(nullptr, targetToJoin);
|
||||
out << "Params:";
|
||||
out << " " + params.join(' ');
|
||||
out << "";
|
||||
|
||||
// window size
|
||||
QString windowParams;
|
||||
if (settings->get("LaunchMaximized").toBool()) {
|
||||
out << "Window size: max (if available)";
|
||||
@ -1031,7 +1043,7 @@ Task::Ptr MinecraftInstance::createUpdateTask(Net::Mode mode)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||
shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin)
|
||||
{
|
||||
updateRuntimeContext();
|
||||
// FIXME: get rid of shared_from_this ...
|
||||
@ -1050,16 +1062,23 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
||||
process->appendStep(makeShared<CreateGameFolders>(pptr));
|
||||
}
|
||||
|
||||
if (!serverToJoin && settings()->get("JoinServerOnLaunch").toBool()) {
|
||||
if (!targetToJoin && settings()->get("JoinOnLaunch").toBool()) {
|
||||
QString fullAddress = settings()->get("JoinServerOnLaunchAddress").toString();
|
||||
serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(fullAddress)));
|
||||
if (!fullAddress.isEmpty()) {
|
||||
targetToJoin.reset(new MinecraftTarget(MinecraftTarget::parse(fullAddress, false)));
|
||||
} else {
|
||||
QString world = settings()->get("JoinWorldOnLaunch").toString();
|
||||
if (!world.isEmpty()) {
|
||||
targetToJoin.reset(new MinecraftTarget(MinecraftTarget::parse(world, true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (serverToJoin && serverToJoin->port == 25565) {
|
||||
if (targetToJoin && targetToJoin->port == 25565) {
|
||||
// Resolve server address to join on launch
|
||||
auto step = makeShared<LookupServerAddress>(pptr);
|
||||
step->setLookupAddress(serverToJoin->address);
|
||||
step->setOutputAddressPtr(serverToJoin);
|
||||
step->setLookupAddress(targetToJoin->address);
|
||||
step->setOutputAddressPtr(targetToJoin);
|
||||
process->appendStep(step);
|
||||
}
|
||||
|
||||
@ -1098,7 +1117,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
||||
|
||||
// print some instance info here...
|
||||
{
|
||||
process->appendStep(makeShared<PrintInstanceInfo>(pptr, session, serverToJoin));
|
||||
process->appendStep(makeShared<PrintInstanceInfo>(pptr, session, targetToJoin));
|
||||
}
|
||||
|
||||
// extract native jars if needed
|
||||
@ -1121,7 +1140,7 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
||||
auto step = makeShared<LauncherPartLaunch>(pptr);
|
||||
step->setWorkingDirectory(gameRoot());
|
||||
step->setAuthSession(session);
|
||||
step->setServerToJoin(serverToJoin);
|
||||
step->setTargetToJoin(targetToJoin);
|
||||
process->appendStep(step);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include "BaseInstance.h"
|
||||
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
#include "minecraft/mod/Mod.h"
|
||||
|
||||
class ModFolderModel;
|
||||
@ -121,11 +121,11 @@ class MinecraftInstance : public BaseInstance {
|
||||
|
||||
////// Launch stuff //////
|
||||
Task::Ptr createUpdateTask(Net::Mode mode) override;
|
||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
|
||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftTarget::Ptr targetToJoin) override;
|
||||
QStringList extraArguments() override;
|
||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin) override;
|
||||
QList<Mod*> getJarMods() const;
|
||||
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
|
||||
QString createLaunchScript(AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin);
|
||||
/// get arguments passed to java
|
||||
QStringList javaArguments();
|
||||
QString getLauncher();
|
||||
@ -155,7 +155,7 @@ class MinecraftInstance : public BaseInstance {
|
||||
virtual QString getMainClass() const;
|
||||
|
||||
// FIXME: remove
|
||||
virtual QStringList processMinecraftArgs(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) const;
|
||||
virtual QStringList processMinecraftArgs(AuthSessionPtr account, MinecraftTarget::Ptr targetToJoin) const;
|
||||
|
||||
virtual JavaVersion getJavaVersion();
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
#include "net/Download.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
EntitlementsStep::EntitlementsStep(AccountData* data) : AuthStep(data) {}
|
||||
@ -33,7 +33,7 @@ void EntitlementsStep::perform()
|
||||
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Download::makeByteArray(url, m_response);
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("EntitlementsStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "Logging.h"
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
#include "net/NetUtils.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) {}
|
||||
@ -38,7 +38,7 @@ void LauncherLoginStep::perform()
|
||||
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Upload::makeByteArray(url, m_response, requestBody.toUtf8());
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("LauncherLoginStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
#include "Application.h"
|
||||
#include "Json.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
// https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-device-code
|
||||
MSADeviceCodeStep::MSADeviceCodeStep(AccountData* data) : AuthStep(data)
|
||||
@ -68,7 +68,7 @@ void MSADeviceCodeStep::perform()
|
||||
};
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Upload::makeByteArray(url, m_response, payload);
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("MSADeviceCodeStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
@ -183,7 +183,7 @@ void MSADeviceCodeStep::authenticateUser()
|
||||
};
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Upload::makeByteArray(url, m_response, payload);
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
connect(m_request.get(), &Task::finished, this, &MSADeviceCodeStep::authenticationFinished);
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "Application.h"
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
#include "net/NetUtils.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
MinecraftProfileStep::MinecraftProfileStep(AccountData* data) : AuthStep(data) {}
|
||||
|
||||
@ -23,7 +23,7 @@ void MinecraftProfileStep::perform()
|
||||
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Download::makeByteArray(url, m_response);
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("MinecraftProfileStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "Logging.h"
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
#include "net/NetUtils.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
XboxAuthorizationStep::XboxAuthorizationStep(AccountData* data, Token* token, QString relyingParty, QString authorizationKind)
|
||||
@ -43,7 +43,7 @@ void XboxAuthorizationStep::perform()
|
||||
};
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8());
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("XboxAuthorizationStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Application.h"
|
||||
#include "Logging.h"
|
||||
#include "net/NetUtils.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
XboxProfileStep::XboxProfileStep(AccountData* data) : AuthStep(data) {}
|
||||
|
||||
@ -35,7 +35,7 @@ void XboxProfileStep::perform()
|
||||
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Download::makeByteArray(url, m_response);
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("XboxProfileStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "Application.h"
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
#include "net/NetUtils.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
XboxUserStep::XboxUserStep(AccountData* data) : AuthStep(data) {}
|
||||
|
||||
@ -39,7 +39,7 @@ void XboxUserStep::perform()
|
||||
};
|
||||
m_response.reset(new QByteArray());
|
||||
m_request = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8());
|
||||
m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
m_task.reset(new NetJob("XboxUserStep", APPLICATION->network()));
|
||||
m_task->setAskRetry(false);
|
||||
|
@ -90,7 +90,7 @@ void LauncherPartLaunch::executeTask()
|
||||
}
|
||||
}
|
||||
|
||||
m_launchScript = minecraftInstance->createLaunchScript(m_session, m_serverToJoin);
|
||||
m_launchScript = minecraftInstance->createLaunchScript(m_session, m_targetToJoin);
|
||||
QStringList args = minecraftInstance->javaArguments();
|
||||
QString allArgs = args.join(", ");
|
||||
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::Launcher);
|
||||
|
@ -19,13 +19,13 @@
|
||||
#include <launch/LaunchStep.h>
|
||||
#include <minecraft/auth/AuthSession.h>
|
||||
|
||||
#include "MinecraftServerTarget.h"
|
||||
#include "MinecraftTarget.h"
|
||||
|
||||
class LauncherPartLaunch : public LaunchStep {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LauncherPartLaunch(LaunchTask* parent);
|
||||
virtual ~LauncherPartLaunch() {};
|
||||
virtual ~LauncherPartLaunch() = default;
|
||||
|
||||
virtual void executeTask();
|
||||
virtual bool abort();
|
||||
@ -34,7 +34,7 @@ class LauncherPartLaunch : public LaunchStep {
|
||||
void setWorkingDirectory(const QString& wd);
|
||||
void setAuthSession(AuthSessionPtr session) { m_session = session; }
|
||||
|
||||
void setServerToJoin(MinecraftServerTargetPtr serverToJoin) { m_serverToJoin = std::move(serverToJoin); }
|
||||
void setTargetToJoin(MinecraftTarget::Ptr targetToJoin) { m_targetToJoin = std::move(targetToJoin); }
|
||||
|
||||
private slots:
|
||||
void on_state(LoggedProcess::State state);
|
||||
@ -44,7 +44,7 @@ class LauncherPartLaunch : public LaunchStep {
|
||||
QString m_command;
|
||||
AuthSessionPtr m_session;
|
||||
QString m_launchScript;
|
||||
MinecraftServerTargetPtr m_serverToJoin;
|
||||
MinecraftTarget::Ptr m_targetToJoin;
|
||||
|
||||
bool mayProceed = false;
|
||||
};
|
||||
|
@ -13,13 +13,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MinecraftServerTarget.h"
|
||||
#include "MinecraftTarget.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
// FIXME: the way this is written, it can't ever do any sort of validation and can accept total junk
|
||||
MinecraftServerTarget MinecraftServerTarget::parse(const QString& fullAddress)
|
||||
MinecraftTarget MinecraftTarget::parse(const QString& fullAddress, bool useWorld)
|
||||
{
|
||||
if (useWorld) {
|
||||
MinecraftTarget target;
|
||||
target.world = fullAddress;
|
||||
return target;
|
||||
}
|
||||
QStringList split = fullAddress.split(":");
|
||||
|
||||
// The logic below replicates the exact logic minecraft uses for parsing server addresses.
|
||||
@ -56,5 +61,5 @@ MinecraftServerTarget MinecraftServerTarget::parse(const QString& fullAddress)
|
||||
}
|
||||
}
|
||||
|
||||
return MinecraftServerTarget{ realAddress, realPort };
|
||||
return MinecraftTarget{ realAddress, realPort };
|
||||
}
|
@ -19,11 +19,11 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
struct MinecraftServerTarget {
|
||||
struct MinecraftTarget {
|
||||
QString address;
|
||||
quint16 port;
|
||||
|
||||
static MinecraftServerTarget parse(const QString& fullAddress);
|
||||
QString world;
|
||||
static MinecraftTarget parse(const QString& fullAddress, bool useWorld);
|
||||
using Ptr = std::shared_ptr<MinecraftTarget>;
|
||||
};
|
||||
|
||||
using MinecraftServerTargetPtr = std::shared_ptr<MinecraftServerTarget>;
|
@ -129,6 +129,6 @@ void PrintInstanceInfo::executeTask()
|
||||
#endif
|
||||
|
||||
logLines(log, MessageLevel::Launcher);
|
||||
logLines(instance->verboseDescription(m_session, m_serverToJoin), MessageLevel::Launcher);
|
||||
logLines(instance->verboseDescription(m_session, m_targetToJoin), MessageLevel::Launcher);
|
||||
emitSucceeded();
|
||||
}
|
||||
|
@ -16,22 +16,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <launch/LaunchStep.h>
|
||||
#include <memory>
|
||||
#include "minecraft/auth/AuthSession.h"
|
||||
#include "minecraft/launch/MinecraftServerTarget.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
|
||||
// FIXME: temporary wrapper for existing task.
|
||||
class PrintInstanceInfo : public LaunchStep {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PrintInstanceInfo(LaunchTask* parent, AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||
: LaunchStep(parent), m_session(session), m_serverToJoin(serverToJoin) {};
|
||||
virtual ~PrintInstanceInfo() {};
|
||||
explicit PrintInstanceInfo(LaunchTask* parent, AuthSessionPtr session, MinecraftTarget::Ptr targetToJoin)
|
||||
: LaunchStep(parent), m_session(session), m_targetToJoin(targetToJoin) {};
|
||||
virtual ~PrintInstanceInfo() = default;
|
||||
|
||||
virtual void executeTask();
|
||||
virtual bool canAbort() const { return false; }
|
||||
|
||||
private:
|
||||
AuthSessionPtr m_session;
|
||||
MinecraftServerTargetPtr m_serverToJoin;
|
||||
MinecraftTarget::Ptr m_targetToJoin;
|
||||
};
|
||||
|
@ -251,7 +251,7 @@ Task* ModFolderModel::createParseTask(Resource& resource)
|
||||
bool ModFolderModel::uninstallMod(const QString& filename, bool preserve_metadata)
|
||||
{
|
||||
for (auto mod : allMods()) {
|
||||
if (mod->fileinfo().fileName() == filename) {
|
||||
if (mod->getOriginalFileName() == filename) {
|
||||
auto index_dir = indexDir();
|
||||
mod->destroy(index_dir, preserve_metadata, false);
|
||||
|
||||
|
@ -197,3 +197,11 @@ bool Resource::isMoreThanOneHardLink() const
|
||||
{
|
||||
return FS::hardLinkCount(m_file_info.absoluteFilePath()) > 1;
|
||||
}
|
||||
|
||||
auto Resource::getOriginalFileName() const -> QString
|
||||
{
|
||||
auto fileName = m_file_info.fileName();
|
||||
if (!m_enabled)
|
||||
fileName.chop(9);
|
||||
return fileName;
|
||||
}
|
@ -80,6 +80,7 @@ class Resource : public QObject {
|
||||
[[nodiscard]] auto internal_id() const -> QString { return m_internal_id; }
|
||||
[[nodiscard]] auto type() const -> ResourceType { return m_type; }
|
||||
[[nodiscard]] bool enabled() const { return m_enabled; }
|
||||
[[nodiscard]] auto getOriginalFileName() const -> QString;
|
||||
[[nodiscard]] QString sizeStr() const { return m_size_str; }
|
||||
[[nodiscard]] qint64 sizeInfo() const { return m_size_info; }
|
||||
|
||||
|
@ -39,9 +39,9 @@
|
||||
#include <memory>
|
||||
|
||||
#include "net/ByteArraySink.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
CapeChange::CapeChange(QString token, QString cape) : NetRequest(), m_capeId(cape), m_token(token)
|
||||
CapeChange::CapeChange(QString cape) : NetRequest(), m_capeId(cape)
|
||||
{
|
||||
logCat = taskMCSkinsLogC;
|
||||
}
|
||||
@ -57,18 +57,14 @@ QNetworkReply* CapeChange::getReply(QNetworkRequest& request)
|
||||
}
|
||||
}
|
||||
|
||||
void CapeChange::init()
|
||||
{
|
||||
addHeaderProxy(new Net::StaticHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit() },
|
||||
}));
|
||||
}
|
||||
|
||||
CapeChange::Ptr CapeChange::make(QString token, QString capeId)
|
||||
{
|
||||
auto up = makeShared<CapeChange>(token, capeId);
|
||||
auto up = makeShared<CapeChange>(capeId);
|
||||
up->m_url = QUrl("https://api.minecraftservices.com/minecraft/profile/capes/active");
|
||||
up->setObjectName(QString("BYTES:") + up->m_url.toString());
|
||||
up->m_sink.reset(new Net::ByteArraySink(std::make_shared<QByteArray>()));
|
||||
up->addHeaderProxy(new Net::RawHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Bearer %1").arg(token).toLocal8Bit() },
|
||||
}));
|
||||
return up;
|
||||
}
|
||||
|
@ -24,16 +24,14 @@ class CapeChange : public Net::NetRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<CapeChange>;
|
||||
CapeChange(QString token, QString capeId);
|
||||
CapeChange(QString capeId);
|
||||
virtual ~CapeChange() = default;
|
||||
|
||||
static CapeChange::Ptr make(QString token, QString capeId);
|
||||
void init() override;
|
||||
|
||||
protected:
|
||||
virtual QNetworkReply* getReply(QNetworkRequest&) override;
|
||||
|
||||
private:
|
||||
QString m_capeId;
|
||||
QString m_token;
|
||||
};
|
||||
|
@ -37,9 +37,9 @@
|
||||
#include "SkinDelete.h"
|
||||
|
||||
#include "net/ByteArraySink.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
SkinDelete::SkinDelete(QString token) : NetRequest(), m_token(token)
|
||||
SkinDelete::SkinDelete() : NetRequest()
|
||||
{
|
||||
logCat = taskMCSkinsLogC;
|
||||
}
|
||||
@ -50,17 +50,13 @@ QNetworkReply* SkinDelete::getReply(QNetworkRequest& request)
|
||||
return m_network->deleteResource(request);
|
||||
}
|
||||
|
||||
void SkinDelete::init()
|
||||
{
|
||||
addHeaderProxy(new Net::StaticHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit() },
|
||||
}));
|
||||
}
|
||||
|
||||
SkinDelete::Ptr SkinDelete::make(QString token)
|
||||
{
|
||||
auto up = makeShared<SkinDelete>(token);
|
||||
auto up = makeShared<SkinDelete>();
|
||||
up->m_url = QUrl("https://api.minecraftservices.com/minecraft/profile/skins/active");
|
||||
up->m_sink.reset(new Net::ByteArraySink(std::make_shared<QByteArray>()));
|
||||
up->addHeaderProxy(new Net::RawHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Bearer %1").arg(token).toLocal8Bit() },
|
||||
}));
|
||||
return up;
|
||||
}
|
||||
|
@ -24,15 +24,11 @@ class SkinDelete : public Net::NetRequest {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<SkinDelete>;
|
||||
SkinDelete(QString token);
|
||||
SkinDelete();
|
||||
virtual ~SkinDelete() = default;
|
||||
|
||||
static SkinDelete::Ptr make(QString token);
|
||||
void init() override;
|
||||
|
||||
protected:
|
||||
virtual QNetworkReply* getReply(QNetworkRequest&) override;
|
||||
|
||||
private:
|
||||
QString m_token;
|
||||
};
|
||||
|
@ -40,9 +40,9 @@
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "net/ByteArraySink.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
SkinUpload::SkinUpload(QString token, QString path, QString variant) : NetRequest(), m_token(token), m_path(path), m_variant(variant)
|
||||
SkinUpload::SkinUpload(QString path, QString variant) : NetRequest(), m_path(path), m_variant(variant)
|
||||
{
|
||||
logCat = taskMCSkinsLogC;
|
||||
}
|
||||
@ -67,18 +67,14 @@ QNetworkReply* SkinUpload::getReply(QNetworkRequest& request)
|
||||
return m_network->post(request, multiPart);
|
||||
}
|
||||
|
||||
void SkinUpload::init()
|
||||
{
|
||||
addHeaderProxy(new Net::StaticHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Bearer %1").arg(m_token).toLocal8Bit() },
|
||||
}));
|
||||
}
|
||||
|
||||
SkinUpload::Ptr SkinUpload::make(QString token, QString path, QString variant)
|
||||
{
|
||||
auto up = makeShared<SkinUpload>(token, path, variant);
|
||||
auto up = makeShared<SkinUpload>(path, variant);
|
||||
up->m_url = QUrl("https://api.minecraftservices.com/minecraft/profile/skins");
|
||||
up->setObjectName(QString("BYTES:") + up->m_url.toString());
|
||||
up->m_sink.reset(new Net::ByteArraySink(std::make_shared<QByteArray>()));
|
||||
up->addHeaderProxy(new Net::RawHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Bearer %1").arg(token).toLocal8Bit() },
|
||||
}));
|
||||
return up;
|
||||
}
|
||||
|
@ -26,17 +26,15 @@ class SkinUpload : public Net::NetRequest {
|
||||
using Ptr = shared_qobject_ptr<SkinUpload>;
|
||||
|
||||
// Note this class takes ownership of the file.
|
||||
SkinUpload(QString token, QString path, QString variant);
|
||||
SkinUpload(QString path, QString variant);
|
||||
virtual ~SkinUpload() = default;
|
||||
|
||||
static SkinUpload::Ptr make(QString token, QString path, QString variant);
|
||||
void init() override;
|
||||
|
||||
protected:
|
||||
virtual QNetworkReply* getReply(QNetworkRequest&) override;
|
||||
|
||||
private:
|
||||
QString m_token;
|
||||
QString m_path;
|
||||
QString m_variant;
|
||||
};
|
||||
|
@ -104,7 +104,7 @@ void Flame::FileResolvingTask::netJobFinished()
|
||||
auto url = QString("https://api.modrinth.com/v2/version_file/%1?algorithm=sha1").arg(hash);
|
||||
auto output = std::make_shared<QByteArray>();
|
||||
auto dl = Net::ApiDownload::makeByteArray(QUrl(url), output);
|
||||
QObject::connect(dl.get(), &Net::ApiDownload::succeeded, [&out]() { out.resolved = true; });
|
||||
QObject::connect(dl.get(), &Task::succeeded, [&out]() { out.resolved = true; });
|
||||
|
||||
m_checkJob->addNetAction(dl);
|
||||
blockedProjects.insert(&out, output);
|
||||
@ -176,7 +176,7 @@ void Flame::FileResolvingTask::modrinthCheckFinished()
|
||||
auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(projectId);
|
||||
auto dl = Net::ApiDownload::makeByteArray(url, output);
|
||||
qDebug() << "Fetching url slug for file:" << mod->fileName;
|
||||
QObject::connect(dl.get(), &Net::ApiDownload::succeeded, [block, index, output]() {
|
||||
QObject::connect(dl.get(), &Task::succeeded, [block, index, output]() {
|
||||
auto mod = block->at(index); // use the shared_ptr so it is captured and only freed when we are done
|
||||
auto json = QJsonDocument::fromJson(*output);
|
||||
auto base =
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "FlameCheckUpdate.h"
|
||||
#include "Application.h"
|
||||
#include "FlameAPI.h"
|
||||
#include "FlameModIndex.h"
|
||||
|
||||
@ -124,11 +125,6 @@ void FlameCheckUpdate::executeTask()
|
||||
|
||||
int i = 0;
|
||||
for (auto* mod : m_mods) {
|
||||
if (!mod->enabled()) {
|
||||
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
||||
continue;
|
||||
}
|
||||
|
||||
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
|
||||
setProgress(i++, m_mods.size());
|
||||
|
||||
@ -177,7 +173,7 @@ void FlameCheckUpdate::executeTask()
|
||||
auto download_task = makeShared<ResourceDownloadTask>(pack, latest_ver.value(), m_mods_folder);
|
||||
m_updatable.emplace_back(pack->name, mod->metadata()->hash, old_version, latest_ver->version, latest_ver->version_type,
|
||||
api.getModFileChangelog(latest_ver->addonId.toInt(), latest_ver->fileId.toInt()),
|
||||
ModPlatform::ResourceProvider::FLAME, download_task);
|
||||
ModPlatform::ResourceProvider::FLAME, download_task, mod->enabled());
|
||||
}
|
||||
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver.value()));
|
||||
}
|
||||
|
@ -42,11 +42,6 @@ void ModrinthCheckUpdate::executeTask()
|
||||
auto hashing_task =
|
||||
makeShared<ConcurrentTask>(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
|
||||
for (auto* mod : m_mods) {
|
||||
if (!mod->enabled()) {
|
||||
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto hash = mod->metadata()->hash;
|
||||
|
||||
// Sadly the API can only handle one hash type per call, se we
|
||||
@ -95,8 +90,7 @@ void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr<QByteArray> resp
|
||||
// If the returned project is empty, but we have Modrinth metadata,
|
||||
// it means this specific version is not available
|
||||
if (project_obj.isEmpty()) {
|
||||
qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response."
|
||||
<< "Hash: " << hash;
|
||||
qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response." << "Hash: " << hash;
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -153,7 +147,7 @@ void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr<QByteArray> resp
|
||||
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.version_type,
|
||||
project_ver.changelog, ModPlatform::ResourceProvider::MODRINTH, download_task);
|
||||
project_ver.changelog, ModPlatform::ResourceProvider::MODRINTH, download_task, mod->enabled());
|
||||
}
|
||||
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, project_ver));
|
||||
}
|
||||
|
@ -18,47 +18,29 @@
|
||||
*/
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
#include "ByteArraySink.h"
|
||||
#include "ChecksumValidator.h"
|
||||
#include "MetaCacheSink.h"
|
||||
#include "net/ApiHeaderProxy.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
auto ApiDownload::makeCached(QUrl url, MetaEntryPtr entry, Options options) -> Download::Ptr
|
||||
Download::Ptr ApiDownload::makeCached(QUrl url, MetaEntryPtr entry, Download::Options options)
|
||||
{
|
||||
auto dl = makeShared<ApiDownload>();
|
||||
dl->m_url = url;
|
||||
dl->setObjectName(QString("CACHE:") + url.toString());
|
||||
dl->m_options = options;
|
||||
auto md5Node = new ChecksumValidator(QCryptographicHash::Md5);
|
||||
auto cachedNode = new MetaCacheSink(entry, md5Node, options.testFlag(Option::MakeEternal));
|
||||
dl->m_sink.reset(cachedNode);
|
||||
auto dl = Download::makeCached(url, entry, options);
|
||||
dl->addHeaderProxy(new ApiHeaderProxy());
|
||||
return dl;
|
||||
}
|
||||
|
||||
auto ApiDownload::makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, Options options) -> Download::Ptr
|
||||
Download::Ptr ApiDownload::makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, Download::Options options)
|
||||
{
|
||||
auto dl = makeShared<ApiDownload>();
|
||||
dl->m_url = url;
|
||||
dl->setObjectName(QString("BYTES:") + url.toString());
|
||||
dl->m_options = options;
|
||||
dl->m_sink.reset(new ByteArraySink(output));
|
||||
auto dl = Download::makeByteArray(url, output, options);
|
||||
dl->addHeaderProxy(new ApiHeaderProxy());
|
||||
return dl;
|
||||
}
|
||||
|
||||
auto ApiDownload::makeFile(QUrl url, QString path, Options options) -> Download::Ptr
|
||||
Download::Ptr ApiDownload::makeFile(QUrl url, QString path, Download::Options options)
|
||||
{
|
||||
auto dl = makeShared<ApiDownload>();
|
||||
dl->m_url = url;
|
||||
dl->setObjectName(QString("FILE:") + url.toString());
|
||||
dl->m_options = options;
|
||||
dl->m_sink.reset(new FileSink(path));
|
||||
auto dl = Download::makeFile(url, path, options);
|
||||
dl->addHeaderProxy(new ApiHeaderProxy());
|
||||
return dl;
|
||||
}
|
||||
|
||||
void ApiDownload::init()
|
||||
{
|
||||
auto api_headers = new ApiHeaderProxy();
|
||||
addHeaderProxy(api_headers);
|
||||
}
|
||||
} // namespace Net
|
||||
|
@ -19,20 +19,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ApiHeaderProxy.h"
|
||||
#include "Download.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
class ApiDownload : public Download {
|
||||
public:
|
||||
virtual ~ApiDownload() = default;
|
||||
|
||||
static auto makeCached(QUrl url, MetaEntryPtr entry, Options options = Option::NoOptions) -> Download::Ptr;
|
||||
static auto makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, Options options = Option::NoOptions) -> Download::Ptr;
|
||||
static auto makeFile(QUrl url, QString path, Options options = Option::NoOptions) -> Download::Ptr;
|
||||
|
||||
void init() override;
|
||||
};
|
||||
namespace ApiDownload {
|
||||
Download::Ptr makeCached(QUrl url, MetaEntryPtr entry, Download::Options options = Download::Option::NoOptions);
|
||||
Download::Ptr makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, Download::Options options = Download::Option::NoOptions);
|
||||
Download::Ptr makeFile(QUrl url, QString path, Download::Options options = Download::Option::NoOptions);
|
||||
}; // namespace ApiDownload
|
||||
|
||||
} // namespace Net
|
||||
|
@ -18,22 +18,15 @@
|
||||
*/
|
||||
|
||||
#include "net/ApiUpload.h"
|
||||
#include "ByteArraySink.h"
|
||||
#include "net/ApiHeaderProxy.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
Upload::Ptr ApiUpload::makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, QByteArray m_post_data)
|
||||
{
|
||||
auto up = makeShared<ApiUpload>();
|
||||
up->m_url = std::move(url);
|
||||
up->m_sink.reset(new ByteArraySink(output));
|
||||
up->m_post_data = std::move(m_post_data);
|
||||
auto up = Upload::makeByteArray(url, output, m_post_data);
|
||||
up->addHeaderProxy(new ApiHeaderProxy());
|
||||
return up;
|
||||
}
|
||||
|
||||
void ApiUpload::init()
|
||||
{
|
||||
auto api_headers = new ApiHeaderProxy();
|
||||
addHeaderProxy(api_headers);
|
||||
}
|
||||
} // namespace Net
|
||||
|
@ -19,18 +19,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ApiHeaderProxy.h"
|
||||
#include "Upload.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
class ApiUpload : public Upload {
|
||||
public:
|
||||
virtual ~ApiUpload() = default;
|
||||
|
||||
static Upload::Ptr makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, QByteArray m_post_data);
|
||||
|
||||
void init() override;
|
||||
namespace ApiUpload {
|
||||
Upload::Ptr makeByteArray(QUrl url, std::shared_ptr<QByteArray> output, QByteArray m_post_data);
|
||||
};
|
||||
|
||||
} // namespace Net
|
||||
|
@ -62,8 +62,6 @@ void NetRequest::addValidator(Validator* v)
|
||||
|
||||
void NetRequest::executeTask()
|
||||
{
|
||||
init();
|
||||
|
||||
setStatus(tr("Requesting %1").arg(StringUtils::truncateUrlHumanFriendly(m_url, 80)));
|
||||
|
||||
if (getState() == Task::State::AbortedByUser) {
|
||||
|
@ -72,8 +72,6 @@ class NetRequest : public Task {
|
||||
void setNetwork(shared_qobject_ptr<QNetworkAccessManager> network) { m_network = network; }
|
||||
void addHeaderProxy(Net::HeaderProxy* proxy) { m_headerProxies.push_back(std::shared_ptr<Net::HeaderProxy>(proxy)); }
|
||||
|
||||
virtual void init() {}
|
||||
|
||||
QUrl url() const;
|
||||
void setUrl(QUrl url) { m_url = url; }
|
||||
int replyStatusCode() const;
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
|
||||
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
||||
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||
* Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -27,7 +28,7 @@ namespace Net {
|
||||
|
||||
class RawHeaderProxy : public HeaderProxy {
|
||||
public:
|
||||
RawHeaderProxy() : HeaderProxy() {}
|
||||
RawHeaderProxy(QList<HeaderPair> headers = {}) : HeaderProxy(), m_headers(std::move(headers)) {};
|
||||
virtual ~RawHeaderProxy() = default;
|
||||
|
||||
public:
|
||||
@ -36,6 +37,7 @@ class RawHeaderProxy : public HeaderProxy {
|
||||
void addHeader(const HeaderPair& header) { m_headers.append(header); }
|
||||
void addHeader(const QByteArray& headerName, const QByteArray& headerValue) { m_headers.append({ headerName, headerValue }); }
|
||||
void addHeaders(const QList<HeaderPair>& headers) { m_headers.append(headers); }
|
||||
void setHeaders(QList<HeaderPair> headers) { m_headers = headers; };
|
||||
|
||||
private:
|
||||
QList<HeaderPair> m_headers;
|
||||
|
@ -1,39 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/HeaderProxy.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
class StaticHeaderProxy : public HeaderProxy {
|
||||
public:
|
||||
StaticHeaderProxy(QList<HeaderPair> hdrs = {}) : HeaderProxy(), m_hdrs(hdrs) {};
|
||||
virtual ~StaticHeaderProxy() = default;
|
||||
|
||||
public:
|
||||
virtual QList<HeaderPair> headers(const QNetworkRequest&) const override { return m_hdrs; };
|
||||
void setHeaders(QList<HeaderPair> hdrs) { m_hdrs = hdrs; };
|
||||
|
||||
private:
|
||||
QList<HeaderPair> m_hdrs;
|
||||
};
|
||||
|
||||
} // namespace Net
|
@ -46,7 +46,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "BuildConfig.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
Net::NetRequest::Ptr ImgurAlbumCreation::make(std::shared_ptr<ImgurAlbumCreation::Result> output, QList<ScreenShot::Ptr> screenshots)
|
||||
{
|
||||
@ -54,6 +54,10 @@ Net::NetRequest::Ptr ImgurAlbumCreation::make(std::shared_ptr<ImgurAlbumCreation
|
||||
up->m_url = BuildConfig.IMGUR_BASE_URL + "album";
|
||||
up->m_sink.reset(new Sink(output));
|
||||
up->m_screenshots = screenshots;
|
||||
up->addHeaderProxy(new Net::RawHeaderProxy(
|
||||
QList<Net::HeaderPair>{ { "Content-Type", "application/x-www-form-urlencoded" },
|
||||
{ "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toUtf8() },
|
||||
{ "Accept", "application/json" } }));
|
||||
return up;
|
||||
}
|
||||
|
||||
@ -67,16 +71,6 @@ QNetworkReply* ImgurAlbumCreation::getReply(QNetworkRequest& request)
|
||||
return m_network->post(request, data);
|
||||
}
|
||||
|
||||
void ImgurAlbumCreation::init()
|
||||
{
|
||||
qDebug() << "Setting up imgur upload";
|
||||
auto api_headers = new Net::StaticHeaderProxy(
|
||||
QList<Net::HeaderPair>{ { "Content-Type", "application/x-www-form-urlencoded" },
|
||||
{ "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toUtf8() },
|
||||
{ "Accept", "application/json" } });
|
||||
addHeaderProxy(api_headers);
|
||||
}
|
||||
|
||||
auto ImgurAlbumCreation::Sink::init(QNetworkRequest& request) -> Task::State
|
||||
{
|
||||
m_output.clear();
|
||||
|
@ -67,8 +67,6 @@ class ImgurAlbumCreation : public Net::NetRequest {
|
||||
static NetRequest::Ptr make(std::shared_ptr<Result> output, QList<ScreenShot::Ptr> screenshots);
|
||||
QNetworkReply* getReply(QNetworkRequest& request) override;
|
||||
|
||||
void init() override;
|
||||
|
||||
private:
|
||||
QList<ScreenShot::Ptr> m_screenshots;
|
||||
};
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include "ImgurUpload.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
@ -47,14 +47,6 @@
|
||||
#include <QNetworkRequest>
|
||||
#include <QUrl>
|
||||
|
||||
void ImgurUpload::init()
|
||||
{
|
||||
qDebug() << "Setting up imgur upload";
|
||||
auto api_headers = new Net::StaticHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toUtf8() }, { "Accept", "application/json" } });
|
||||
addHeaderProxy(api_headers);
|
||||
}
|
||||
|
||||
QNetworkReply* ImgurUpload::getReply(QNetworkRequest& request)
|
||||
{
|
||||
auto file = new QFile(m_fileInfo.absoluteFilePath(), this);
|
||||
@ -125,5 +117,7 @@ Net::NetRequest::Ptr ImgurUpload::make(ScreenShot::Ptr m_shot)
|
||||
auto up = makeShared<ImgurUpload>(m_shot->m_file);
|
||||
up->m_url = std::move(BuildConfig.IMGUR_BASE_URL + "image");
|
||||
up->m_sink.reset(new Sink(m_shot));
|
||||
up->addHeaderProxy(new Net::RawHeaderProxy(QList<Net::HeaderPair>{
|
||||
{ "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toUtf8() }, { "Accept", "application/json" } }));
|
||||
return up;
|
||||
}
|
||||
|
@ -62,8 +62,6 @@ class ImgurUpload : public Net::NetRequest {
|
||||
|
||||
static NetRequest::Ptr make(ScreenShot::Ptr m_shot);
|
||||
|
||||
void init() override;
|
||||
|
||||
private:
|
||||
virtual QNetworkReply* getReply(QNetworkRequest&) override;
|
||||
const QFileInfo m_fileInfo;
|
||||
|
@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
#include "ProfileSetupDialog.h"
|
||||
#include "net/RawHeaderProxy.h"
|
||||
#include "ui_ProfileSetupDialog.h"
|
||||
|
||||
#include <QAction>
|
||||
@ -46,7 +47,6 @@
|
||||
|
||||
#include <Application.h>
|
||||
#include "minecraft/auth/Parsers.h"
|
||||
#include "net/StaticHeaderProxy.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget* parent)
|
||||
@ -160,7 +160,7 @@ void ProfileSetupDialog::checkName(const QString& name)
|
||||
if (m_check_task)
|
||||
disconnect(m_check_task.get(), nullptr, this, nullptr);
|
||||
m_check_task = Net::Download::makeByteArray(url, m_check_response);
|
||||
m_check_task->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_check_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
connect(m_check_task.get(), &Task::finished, this, &ProfileSetupDialog::checkFinished);
|
||||
|
||||
@ -204,7 +204,7 @@ void ProfileSetupDialog::setupProfile(const QString& profileName)
|
||||
|
||||
m_profile_response.reset(new QByteArray());
|
||||
m_profile_task = Net::Upload::makeByteArray(url, m_profile_response, payloadTemplate.arg(profileName).toUtf8());
|
||||
m_profile_task->addHeaderProxy(new Net::StaticHeaderProxy(headers));
|
||||
m_profile_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||
|
||||
connect(m_profile_task.get(), &Task::finished, this, &ProfileSetupDialog::setupProfileFinished);
|
||||
|
||||
|
@ -36,6 +36,8 @@
|
||||
*/
|
||||
|
||||
#include "InstanceSettingsPage.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/WorldList.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/java/InstallJavaDialog.h"
|
||||
#include "ui_InstanceSettingsPage.h"
|
||||
@ -75,6 +77,22 @@ InstanceSettingsPage::InstanceSettingsPage(BaseInstance* inst, QWidget* parent)
|
||||
connect(ui->useNativeGLFWCheck, &QAbstractButton::toggled, this, &InstanceSettingsPage::onUseNativeGLFWChanged);
|
||||
connect(ui->useNativeOpenALCheck, &QAbstractButton::toggled, this, &InstanceSettingsPage::onUseNativeOpenALChanged);
|
||||
|
||||
auto mInst = dynamic_cast<MinecraftInstance*>(inst);
|
||||
m_world_quickplay_supported = mInst && mInst->traits().contains("feature:is_quick_play_singleplayer");
|
||||
if (m_world_quickplay_supported) {
|
||||
auto worlds = mInst->worldList();
|
||||
worlds->update();
|
||||
for (const auto& world : worlds->allWorlds()) {
|
||||
ui->worldsCb->addItem(world.folderName());
|
||||
}
|
||||
} else {
|
||||
ui->worldsCb->hide();
|
||||
ui->worldJoinButton->hide();
|
||||
ui->serverJoinAddressButton->setChecked(true);
|
||||
ui->serverJoinAddress->setEnabled(true);
|
||||
ui->serverJoinAddressButton->setStyleSheet("QRadioButton::indicator { width: 0px; height: 0px; }");
|
||||
}
|
||||
|
||||
loadSettings();
|
||||
|
||||
updateThresholds();
|
||||
@ -257,9 +275,16 @@ void InstanceSettingsPage::applySettings()
|
||||
bool joinServerOnLaunch = ui->serverJoinGroupBox->isChecked();
|
||||
m_settings->set("JoinServerOnLaunch", joinServerOnLaunch);
|
||||
if (joinServerOnLaunch) {
|
||||
m_settings->set("JoinServerOnLaunchAddress", ui->serverJoinAddress->text());
|
||||
if (ui->serverJoinAddressButton->isChecked() || !m_world_quickplay_supported) {
|
||||
m_settings->set("JoinServerOnLaunchAddress", ui->serverJoinAddress->text());
|
||||
m_settings->reset("JoinWorldOnLaunch");
|
||||
} else {
|
||||
m_settings->set("JoinWorldOnLaunch", ui->worldsCb->currentText());
|
||||
m_settings->reset("JoinServerOnLaunchAddress");
|
||||
}
|
||||
} else {
|
||||
m_settings->reset("JoinServerOnLaunchAddress");
|
||||
m_settings->reset("JoinWorldOnLaunch");
|
||||
}
|
||||
|
||||
// Use an account for this instance
|
||||
@ -379,7 +404,25 @@ void InstanceSettingsPage::loadSettings()
|
||||
ui->recordGameTime->setChecked(m_settings->get("RecordGameTime").toBool());
|
||||
|
||||
ui->serverJoinGroupBox->setChecked(m_settings->get("JoinServerOnLaunch").toBool());
|
||||
ui->serverJoinAddress->setText(m_settings->get("JoinServerOnLaunchAddress").toString());
|
||||
|
||||
if (auto server = m_settings->get("JoinServerOnLaunchAddress").toString(); !server.isEmpty()) {
|
||||
ui->serverJoinAddress->setText(server);
|
||||
ui->serverJoinAddressButton->setChecked(true);
|
||||
ui->worldJoinButton->setChecked(false);
|
||||
ui->serverJoinAddress->setEnabled(true);
|
||||
ui->worldsCb->setEnabled(false);
|
||||
} else if (auto world = m_settings->get("JoinWorldOnLaunch").toString(); !world.isEmpty() && m_world_quickplay_supported) {
|
||||
ui->worldsCb->setCurrentText(world);
|
||||
ui->serverJoinAddressButton->setChecked(false);
|
||||
ui->worldJoinButton->setChecked(true);
|
||||
ui->serverJoinAddress->setEnabled(false);
|
||||
ui->worldsCb->setEnabled(true);
|
||||
} else {
|
||||
ui->serverJoinAddressButton->setChecked(true);
|
||||
ui->worldJoinButton->setChecked(false);
|
||||
ui->serverJoinAddress->setEnabled(true);
|
||||
ui->worldsCb->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->instanceAccountGroupBox->setChecked(m_settings->get("UseAccountForInstance").toBool());
|
||||
updateAccountsMenu();
|
||||
@ -549,3 +592,13 @@ void InstanceSettingsPage::updateThresholds()
|
||||
ui->labelMaxMemIcon->setPixmap(pix);
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::on_serverJoinAddressButton_toggled(bool checked)
|
||||
{
|
||||
ui->serverJoinAddress->setEnabled(checked);
|
||||
}
|
||||
|
||||
void InstanceSettingsPage::on_worldJoinButton_toggled(bool checked)
|
||||
{
|
||||
ui->worldsCb->setEnabled(checked);
|
||||
}
|
||||
|
@ -71,6 +71,8 @@ class InstanceSettingsPage : public QWidget, public BasePage {
|
||||
void on_javaBrowseBtn_clicked();
|
||||
void on_javaDownloadBtn_clicked();
|
||||
void on_maxMemSpinBox_valueChanged(int i);
|
||||
void on_serverJoinAddressButton_toggled(bool checked);
|
||||
void on_worldJoinButton_toggled(bool checked);
|
||||
|
||||
void onUseNativeGLFWChanged(bool checked);
|
||||
void onUseNativeOpenALChanged(bool checked);
|
||||
@ -91,4 +93,5 @@ class InstanceSettingsPage : public QWidget, public BasePage {
|
||||
BaseInstance* m_instance;
|
||||
SettingsObjectPtr m_settings;
|
||||
unique_qobject_ptr<JavaCommon::TestCheck> checker;
|
||||
bool m_world_quickplay_supported;
|
||||
};
|
||||
|
@ -667,7 +667,7 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="serverJoinGroupBox">
|
||||
<property name="title">
|
||||
<string>Set a server to join on launch</string>
|
||||
<string>Set a target to join on launch</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
@ -675,26 +675,26 @@
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="serverJoinLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="serverJoinAddressLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Server address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="serverJoinAddress"/>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="serverJoinAddressButton">
|
||||
<property name="text">
|
||||
<string>Server address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="serverJoinAddress"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="worldJoinButton">
|
||||
<property name="text">
|
||||
<string>Singleplayer world</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="worldsCb"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -168,7 +168,7 @@ class ServersModel : public QAbstractListModel {
|
||||
m_saveTimer.setInterval(5000);
|
||||
connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
|
||||
}
|
||||
virtual ~ServersModel() {};
|
||||
virtual ~ServersModel() = default;
|
||||
|
||||
void observe()
|
||||
{
|
||||
@ -731,7 +731,7 @@ void ServersPage::on_actionMove_Down_triggered()
|
||||
void ServersPage::on_actionJoin_triggered()
|
||||
{
|
||||
const auto& address = m_model->at(currentServer)->m_address;
|
||||
APPLICATION->launch(m_inst, true, false, std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(address)));
|
||||
APPLICATION->launch(m_inst, true, false, std::make_shared<MinecraftTarget>(MinecraftTarget::parse(address, false)));
|
||||
}
|
||||
|
||||
#include "ServersPage.moc"
|
||||
|
@ -82,7 +82,7 @@ class WorldListProxyModel : public QSortFilterProxyModel {
|
||||
}
|
||||
};
|
||||
|
||||
WorldListPage::WorldListPage(BaseInstance* inst, std::shared_ptr<WorldList> worlds, QWidget* parent)
|
||||
WorldListPage::WorldListPage(InstancePtr inst, std::shared_ptr<WorldList> worlds, QWidget* parent)
|
||||
: QMainWindow(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -113,6 +113,11 @@ void WorldListPage::openedImpl()
|
||||
{
|
||||
m_worlds->startWatching();
|
||||
|
||||
auto mInst = std::dynamic_pointer_cast<MinecraftInstance>(m_inst);
|
||||
if (!mInst || !mInst->traits().contains("feature:is_quick_play_singleplayer")) {
|
||||
ui->toolBar->removeAction(ui->actionJoin);
|
||||
}
|
||||
|
||||
auto const setting_name = QString("WideBarVisibility_%1").arg(id());
|
||||
if (!APPLICATION->settings()->contains(setting_name))
|
||||
m_wide_bar_setting = APPLICATION->settings()->registerSetting(setting_name);
|
||||
@ -339,6 +344,14 @@ void WorldListPage::worldChanged([[maybe_unused]] const QModelIndex& current, [[
|
||||
ui->actionDatapacks->setEnabled(enable);
|
||||
bool hasIcon = !index.data(WorldList::IconFileRole).isNull();
|
||||
ui->actionReset_Icon->setEnabled(enable && hasIcon);
|
||||
|
||||
auto mInst = std::dynamic_pointer_cast<MinecraftInstance>(m_inst);
|
||||
auto supportsJoin = mInst && mInst->traits().contains("feature:is_quick_play_singleplayer");
|
||||
ui->actionJoin->setEnabled(enable && supportsJoin);
|
||||
|
||||
if (!supportsJoin) {
|
||||
ui->toolBar->removeAction(ui->actionJoin);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldListPage::on_actionAdd_triggered()
|
||||
@ -418,4 +431,15 @@ void WorldListPage::on_actionRefresh_triggered()
|
||||
m_worlds->update();
|
||||
}
|
||||
|
||||
void WorldListPage::on_actionJoin_triggered()
|
||||
{
|
||||
QModelIndex index = getSelectedWorld();
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
|
||||
auto world = (World*)worldVariant.value<void*>();
|
||||
APPLICATION->launch(m_inst, true, false, std::make_shared<MinecraftTarget>(MinecraftTarget::parse(world->folderName(), true)));
|
||||
}
|
||||
|
||||
#include "WorldListPage.moc"
|
||||
|
@ -53,7 +53,7 @@ class WorldListPage : public QMainWindow, public BasePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WorldListPage(BaseInstance* inst, std::shared_ptr<WorldList> worlds, QWidget* parent = 0);
|
||||
explicit WorldListPage(InstancePtr inst, std::shared_ptr<WorldList> worlds, QWidget* parent = 0);
|
||||
virtual ~WorldListPage();
|
||||
|
||||
virtual QString displayName() const override { return tr("Worlds"); }
|
||||
@ -72,7 +72,7 @@ class WorldListPage : public QMainWindow, public BasePage {
|
||||
QMenu* createPopupMenu() override;
|
||||
|
||||
protected:
|
||||
BaseInstance* m_inst;
|
||||
InstancePtr m_inst;
|
||||
|
||||
private:
|
||||
QModelIndex getSelectedWorld();
|
||||
@ -101,6 +101,7 @@ class WorldListPage : public QMainWindow, public BasePage {
|
||||
void on_actionReset_Icon_triggered();
|
||||
void worldChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
void mceditState(LoggedProcess::State state);
|
||||
void on_actionJoin_triggered();
|
||||
|
||||
void ShowContextMenu(const QPoint& pos);
|
||||
};
|
||||
|
@ -81,6 +81,7 @@
|
||||
</attribute>
|
||||
<addaction name="actionAdd"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionJoin"/>
|
||||
<addaction name="actionRename"/>
|
||||
<addaction name="actionCopy"/>
|
||||
<addaction name="actionRemove"/>
|
||||
@ -97,6 +98,11 @@
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionJoin">
|
||||
<property name="text">
|
||||
<string>Join</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRename">
|
||||
<property name="text">
|
||||
<string>Rename</string>
|
||||
|
@ -309,4 +309,15 @@ bool WideBar::checkHash(QByteArray const& old_hash) const
|
||||
return old_hash == getHash();
|
||||
}
|
||||
|
||||
void WideBar::removeAction(QAction* action)
|
||||
{
|
||||
auto iter = getMatching(action);
|
||||
if (iter == m_entries.end())
|
||||
return;
|
||||
|
||||
iter->bar_action->setVisible(false);
|
||||
removeAction(iter->bar_action);
|
||||
m_entries.erase(iter);
|
||||
}
|
||||
|
||||
#include "WideBar.moc"
|
||||
|
@ -38,6 +38,8 @@ class WideBar : public QToolBar {
|
||||
[[nodiscard]] QByteArray getVisibilityState() const;
|
||||
void setVisibilityState(QByteArray&&);
|
||||
|
||||
void removeAction(QAction* action);
|
||||
|
||||
private:
|
||||
struct BarEntry {
|
||||
enum class Type { None, Action, Separator, Spacer } type = Type::None;
|
||||
|
@ -70,7 +70,7 @@ public abstract class AbstractLauncher implements Launcher {
|
||||
// secondary parameters
|
||||
protected final int width, height;
|
||||
protected final boolean maximize;
|
||||
protected final String serverAddress, serverPort;
|
||||
protected final String serverAddress, serverPort, worldName;
|
||||
|
||||
protected final String mainClassName;
|
||||
|
||||
@ -80,6 +80,7 @@ public abstract class AbstractLauncher implements Launcher {
|
||||
|
||||
serverAddress = params.getString("serverAddress", null);
|
||||
serverPort = params.getString("serverPort", null);
|
||||
worldName = params.getString("worldName", null);
|
||||
|
||||
String windowParams = params.getString("windowParams", null);
|
||||
|
||||
|
@ -62,13 +62,15 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class StandardLauncher extends AbstractLauncher {
|
||||
private final boolean quickPlaySupported;
|
||||
private final boolean quickPlayMultiplayerSupported;
|
||||
private final boolean quickPlaySingleplayerSupported;
|
||||
|
||||
public StandardLauncher(Parameters params) {
|
||||
super(params);
|
||||
|
||||
List<String> traits = params.getList("traits", Collections.<String>emptyList());
|
||||
quickPlaySupported = traits.contains("feature:is_quick_play_multiplayer");
|
||||
quickPlayMultiplayerSupported = traits.contains("feature:is_quick_play_multiplayer");
|
||||
quickPlaySingleplayerSupported = traits.contains("feature:is_quick_play_singleplayer");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,7 +85,7 @@ public final class StandardLauncher extends AbstractLauncher {
|
||||
}
|
||||
|
||||
if (serverAddress != null) {
|
||||
if (quickPlaySupported) {
|
||||
if (quickPlayMultiplayerSupported) {
|
||||
// as of 23w14a
|
||||
gameArgs.add("--quickPlayMultiplayer");
|
||||
gameArgs.add(serverAddress + ':' + serverPort);
|
||||
@ -93,6 +95,9 @@ public final class StandardLauncher extends AbstractLauncher {
|
||||
gameArgs.add("--port");
|
||||
gameArgs.add(serverPort);
|
||||
}
|
||||
} else if (worldName != null && quickPlaySingleplayerSupported) {
|
||||
gameArgs.add("--quickPlaySingleplayer");
|
||||
gameArgs.add(worldName);
|
||||
}
|
||||
|
||||
// find and invoke the main method
|
||||
|
@ -24,9 +24,8 @@
|
||||
overlays.default = final: prev: let
|
||||
version = builtins.substring 0 8 self.lastModifiedDate or "dirty";
|
||||
in {
|
||||
prismlauncher-unwrapped = prev.qt6Packages.callPackage ./pkg {
|
||||
prismlauncher-unwrapped = prev.callPackage ./pkg {
|
||||
inherit (inputs) libnbtplusplus;
|
||||
inherit ((final.darwin or prev.darwin).apple_sdk.frameworks) Cocoa;
|
||||
inherit version;
|
||||
};
|
||||
|
||||
|
@ -1,27 +1,27 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
canonicalize-jars-hook,
|
||||
cmake,
|
||||
cmark,
|
||||
Cocoa,
|
||||
ninja,
|
||||
jdk17,
|
||||
zlib,
|
||||
qtbase,
|
||||
qtnetworkauth,
|
||||
quazip,
|
||||
darwin,
|
||||
extra-cmake-modules,
|
||||
tomlplusplus,
|
||||
ghc_filesystem,
|
||||
gamemode,
|
||||
ghc_filesystem,
|
||||
jdk17,
|
||||
kdePackages,
|
||||
ninja,
|
||||
stripJavaArchivesHook,
|
||||
tomlplusplus,
|
||||
zlib,
|
||||
msaClientID ? null,
|
||||
gamemodeSupport ? stdenv.isLinux,
|
||||
version,
|
||||
libnbtplusplus,
|
||||
}:
|
||||
assert lib.assertMsg (stdenv.isLinux || !gamemodeSupport) "gamemodeSupport is only available on Linux";
|
||||
stdenv.mkDerivation rec {
|
||||
assert lib.assertMsg (
|
||||
gamemodeSupport -> stdenv.isLinux
|
||||
) "gamemodeSupport is only available on Linux.";
|
||||
stdenv.mkDerivation {
|
||||
pname = "prismlauncher-unwrapped";
|
||||
inherit version;
|
||||
|
||||
@ -39,49 +39,68 @@ assert lib.assertMsg (stdenv.isLinux || !gamemodeSupport) "gamemodeSupport is on
|
||||
]);
|
||||
};
|
||||
|
||||
nativeBuildInputs = [extra-cmake-modules cmake jdk17 ninja canonicalize-jars-hook];
|
||||
buildInputs =
|
||||
[
|
||||
qtbase
|
||||
qtnetworkauth
|
||||
zlib
|
||||
quazip
|
||||
ghc_filesystem
|
||||
tomlplusplus
|
||||
cmark
|
||||
]
|
||||
++ lib.optional gamemodeSupport gamemode
|
||||
++ lib.optionals stdenv.isDarwin [Cocoa];
|
||||
|
||||
hardeningEnable = lib.optionals stdenv.isLinux ["pie"];
|
||||
|
||||
cmakeFlags =
|
||||
[
|
||||
"-DLauncher_BUILD_PLATFORM=nixpkgs"
|
||||
]
|
||||
++ lib.optionals (msaClientID != null) ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"]
|
||||
++ lib.optionals (lib.versionOlder qtbase.version "6") ["-DLauncher_QT_VERSION_MAJOR=5"]
|
||||
++ lib.optionals stdenv.isDarwin ["-DINSTALL_BUNDLE=nodeps" "-DMACOSX_SPARKLE_UPDATE_FEED_URL=''"];
|
||||
|
||||
postUnpack = ''
|
||||
rm -rf source/libraries/libnbtplusplus
|
||||
ln -s ${libnbtplusplus} source/libraries/libnbtplusplus
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
ninja
|
||||
extra-cmake-modules
|
||||
jdk17
|
||||
stripJavaArchivesHook
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
cmark
|
||||
ghc_filesystem
|
||||
kdePackages.qtbase
|
||||
kdePackages.qtnetworkauth
|
||||
kdePackages.quazip
|
||||
tomlplusplus
|
||||
zlib
|
||||
]
|
||||
++ lib.optionals stdenv.isDarwin [darwin.apple_sdk.frameworks.Cocoa]
|
||||
++ lib.optional gamemodeSupport gamemode;
|
||||
|
||||
hardeningEnable = lib.optionals stdenv.isLinux ["pie"];
|
||||
|
||||
cmakeFlags =
|
||||
[
|
||||
(lib.cmakeFeature "Launcher_BUILD_PLATFORM" "nixpkgs")
|
||||
]
|
||||
++ lib.optionals (msaClientID != null) [
|
||||
(lib.cmakeFeature "Launcher_MSA_CLIENT_ID" (toString msaClientID))
|
||||
]
|
||||
++ lib.optionals (lib.versionOlder kdePackages.qtbase.version "6") [
|
||||
(lib.cmakeFeature "Launcher_QT_VERSION_MAJOR" "5")
|
||||
]
|
||||
++ lib.optionals stdenv.isDarwin [
|
||||
# we wrap our binary manually
|
||||
(lib.cmakeFeature "INSTALL_BUNDLE" "nodeps")
|
||||
# disable built-in updater
|
||||
(lib.cmakeFeature "MACOSX_SPARKLE_UPDATE_FEED_URL" "''")
|
||||
(lib.cmakeFeature "CMAKE_INSTALL_PREFIX" "${placeholder "out"}/Applications/")
|
||||
];
|
||||
|
||||
dontWrapQtApps = true;
|
||||
|
||||
meta = with lib; {
|
||||
mainProgram = "prismlauncher";
|
||||
homepage = "https://prismlauncher.org/";
|
||||
description = "A free, open source launcher for Minecraft";
|
||||
meta = {
|
||||
description = "Free, open source launcher for Minecraft";
|
||||
longDescription = ''
|
||||
Allows you to have multiple, separate instances of Minecraft (each with
|
||||
their own mods, texture packs, saves, etc) and helps you manage them and
|
||||
their associated options with a simple interface.
|
||||
'';
|
||||
platforms = with platforms; linux ++ darwin;
|
||||
changelog = "https://github.com/PrismLauncher/PrismLauncher/releases/tag/${version}";
|
||||
license = licenses.gpl3Only;
|
||||
maintainers = with maintainers; [minion3665 Scrumplex getchoo];
|
||||
homepage = "https://prismlauncher.org/";
|
||||
license = lib.licenses.gpl3Only;
|
||||
maintainers = with lib.maintainers; [
|
||||
Scrumplex
|
||||
getchoo
|
||||
];
|
||||
mainProgram = "prismlauncher";
|
||||
platforms = lib.platforms.linux ++ lib.platforms.darwin;
|
||||
};
|
||||
}
|
||||
|
@ -3,94 +3,143 @@
|
||||
stdenv,
|
||||
symlinkJoin,
|
||||
prismlauncher-unwrapped,
|
||||
wrapQtAppsHook,
|
||||
addOpenGLRunpath,
|
||||
qtbase, # needed for wrapQtAppsHook
|
||||
qtsvg,
|
||||
qtwayland,
|
||||
xorg,
|
||||
libpulseaudio,
|
||||
libGL,
|
||||
flite,
|
||||
gamemode,
|
||||
glfw,
|
||||
openal,
|
||||
glfw-wayland-minecraft,
|
||||
glxinfo,
|
||||
jdk8,
|
||||
jdk17,
|
||||
jdk21,
|
||||
gamemode,
|
||||
flite,
|
||||
glxinfo,
|
||||
udev,
|
||||
kdePackages,
|
||||
libGL,
|
||||
libpulseaudio,
|
||||
libusb1,
|
||||
msaClientID ? null,
|
||||
gamemodeSupport ? stdenv.isLinux,
|
||||
textToSpeechSupport ? stdenv.isLinux,
|
||||
controllerSupport ? stdenv.isLinux,
|
||||
jdks ? [jdk21 jdk17 jdk8],
|
||||
makeWrapper,
|
||||
openal,
|
||||
pciutils,
|
||||
udev,
|
||||
vulkan-loader,
|
||||
xorg,
|
||||
additionalLibs ? [],
|
||||
additionalPrograms ? [],
|
||||
}: let
|
||||
prismlauncherFinal = prismlauncher-unwrapped.override {
|
||||
inherit msaClientID gamemodeSupport;
|
||||
};
|
||||
controllerSupport ? stdenv.isLinux,
|
||||
gamemodeSupport ? stdenv.isLinux,
|
||||
jdks ? [
|
||||
jdk21
|
||||
jdk17
|
||||
jdk8
|
||||
],
|
||||
msaClientID ? null,
|
||||
textToSpeechSupport ? stdenv.isLinux,
|
||||
# Adds `glfw-wayland-minecraft` to `LD_LIBRARY_PATH`
|
||||
# when launched on wayland, allowing for the game to be run natively.
|
||||
# Make sure to enable "Use system installation of GLFW" in instance settings
|
||||
# for this to take effect
|
||||
#
|
||||
# Warning: This build of glfw may be unstable, and the launcher
|
||||
# itself can take slightly longer to start
|
||||
withWaylandGLFW ? false,
|
||||
}:
|
||||
assert lib.assertMsg (
|
||||
controllerSupport -> stdenv.isLinux
|
||||
) "controllerSupport only has an effect on Linux.";
|
||||
assert lib.assertMsg (
|
||||
textToSpeechSupport -> stdenv.isLinux
|
||||
) "textToSpeechSupport only has an effect on Linux.";
|
||||
assert lib.assertMsg (
|
||||
withWaylandGLFW -> stdenv.isLinux
|
||||
) "withWaylandGLFW is only available on Linux."; let
|
||||
prismlauncher' = prismlauncher-unwrapped.override {inherit msaClientID gamemodeSupport;};
|
||||
in
|
||||
symlinkJoin {
|
||||
name = "prismlauncher-${prismlauncherFinal.version}";
|
||||
name = "prismlauncher-${prismlauncher'.version}";
|
||||
|
||||
paths = [prismlauncherFinal];
|
||||
paths = [prismlauncher'];
|
||||
|
||||
nativeBuildInputs = [
|
||||
wrapQtAppsHook
|
||||
];
|
||||
nativeBuildInputs =
|
||||
[kdePackages.wrapQtAppsHook]
|
||||
# purposefully using a shell wrapper here for variable expansion
|
||||
# see https://github.com/NixOS/nixpkgs/issues/172583
|
||||
++ lib.optional withWaylandGLFW makeWrapper;
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
qtbase
|
||||
qtsvg
|
||||
kdePackages.qtbase
|
||||
kdePackages.qtsvg
|
||||
]
|
||||
++ lib.optional (lib.versionAtLeast qtbase.version "6" && stdenv.isLinux) qtwayland;
|
||||
++ lib.optional (
|
||||
lib.versionAtLeast kdePackages.qtbase.version "6" && stdenv.isLinux
|
||||
)
|
||||
kdePackages.qtwayland;
|
||||
|
||||
postBuild = ''
|
||||
wrapQtAppsHook
|
||||
'';
|
||||
env = {
|
||||
waylandPreExec = lib.optionalString withWaylandGLFW ''
|
||||
if [ -n "$WAYLAND_DISPLAY" ]; then
|
||||
export LD_LIBRARY_PATH=${lib.getLib glfw-wayland-minecraft}/lib:"$LD_LIBRARY_PATH"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
postBuild =
|
||||
lib.optionalString withWaylandGLFW ''
|
||||
qtWrapperArgs+=(--run "$waylandPreExec")
|
||||
''
|
||||
+ ''
|
||||
wrapQtAppsHook
|
||||
'';
|
||||
|
||||
qtWrapperArgs = let
|
||||
runtimeLibs =
|
||||
(with xorg; [
|
||||
libX11
|
||||
libXext
|
||||
libXcursor
|
||||
libXrandr
|
||||
libXxf86vm
|
||||
])
|
||||
++ [
|
||||
[
|
||||
# lwjgl
|
||||
glfw
|
||||
libpulseaudio
|
||||
libGL
|
||||
glfw
|
||||
openal
|
||||
stdenv.cc.cc.lib
|
||||
|
||||
# oshi
|
||||
udev
|
||||
vulkan-loader # VulkanMod's lwjgl
|
||||
|
||||
udev # oshi
|
||||
|
||||
xorg.libX11
|
||||
xorg.libXext
|
||||
xorg.libXcursor
|
||||
xorg.libXrandr
|
||||
xorg.libXxf86vm
|
||||
]
|
||||
++ lib.optional gamemodeSupport gamemode.lib
|
||||
++ lib.optional textToSpeechSupport flite
|
||||
++ lib.optional gamemodeSupport gamemode.lib
|
||||
++ lib.optional controllerSupport libusb1
|
||||
++ additionalLibs;
|
||||
|
||||
runtimePrograms =
|
||||
[
|
||||
xorg.xrandr
|
||||
glxinfo
|
||||
pciutils # need lspci
|
||||
xorg.xrandr # needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128
|
||||
]
|
||||
++ additionalPrograms;
|
||||
in
|
||||
["--prefix PRISMLAUNCHER_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}"]
|
||||
++ lib.optionals stdenv.isLinux [
|
||||
"--set LD_LIBRARY_PATH ${addOpenGLRunpath.driverLink}/lib:${lib.makeLibraryPath runtimeLibs}"
|
||||
# xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128
|
||||
"--prefix PATH : ${lib.makeBinPath runtimePrograms}"
|
||||
];
|
||||
|
||||
inherit (prismlauncherFinal) meta;
|
||||
meta = {
|
||||
inherit
|
||||
(prismlauncher'.meta)
|
||||
description
|
||||
longDescription
|
||||
homepage
|
||||
changelog
|
||||
license
|
||||
maintainers
|
||||
mainProgram
|
||||
platforms
|
||||
;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user