From e47186e0d51f1de264ab8964f75c9376a017d84a Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Tue, 5 Sep 2023 00:22:57 -0400 Subject: [PATCH 1/4] Port over recent Nix packaging changes from Prism Launcher Resolves https://github.com/fn2006/PollyMC/issues/85 Prism Launcher has refactored a lot of their Nix recently. This includes the changes from https://github.com/PrismLauncher/PrismLauncher/pull/1574, but I'm not 100% sure that's what fixed the issue here, it could have been some other change along the way. Signed-off-by: Evan Goode --- flake.nix | 16 ++++- nix/default.nix | 31 ---------- nix/dev.nix | 38 ++++++------ nix/distribution.nix | 46 +++++++++----- nix/{package.nix => pkg/default.nix} | 0 nix/pkg/wrapper.nix | 91 ++++++++++++++++++++++++++++ 6 files changed, 153 insertions(+), 69 deletions(-) delete mode 100644 nix/default.nix rename nix/{package.nix => pkg/default.nix} (100%) create mode 100644 nix/pkg/wrapper.nix diff --git a/flake.nix b/flake.nix index c3148fe03..d45282aa6 100644 --- a/flake.nix +++ b/flake.nix @@ -23,5 +23,19 @@ outputs = inputs: inputs.flake-parts.lib.mkFlake {inherit inputs;} - {imports = [./nix];}; + { + imports = [ + inputs.pre-commit-hooks.flakeModule + + ./nix/dev.nix + ./nix/distribution.nix + ]; + + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + }; } diff --git a/nix/default.nix b/nix/default.nix deleted file mode 100644 index 71c95c2cf..000000000 --- a/nix/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - inputs, - self, - ... -}: { - imports = [ - ./dev.nix - ./distribution.nix - ]; - - _module.args = { - # User-friendly version number. - version = builtins.substring 0 8 self.lastModifiedDate; - }; - - perSystem = {system, ...}: { - # Nixpkgs instantiated for supported systems with our overlay. - _module.args.pkgs = import inputs.nixpkgs { - inherit system; - overlays = [self.overlays.default]; - }; - }; - - # Supported systems. - systems = [ - "x86_64-linux" - "aarch64-linux" - "x86_64-darwin" - "aarch64-darwin" - ]; -} diff --git a/nix/dev.nix b/nix/dev.nix index a9c1dc65d..aafa6d7af 100644 --- a/nix/dev.nix +++ b/nix/dev.nix @@ -1,37 +1,33 @@ { - inputs, - self, - ... -}: { perSystem = { - system, + config, + lib, pkgs, ... }: { - checks = { - pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run { - src = self; - hooks = { - markdownlint.enable = true; + pre-commit.settings = { + hooks = { + markdownlint.enable = true; - alejandra.enable = true; - deadnix.enable = true; - nil.enable = true; + alejandra.enable = true; + deadnix.enable = true; + nil.enable = true; - clang-format = { - enable = true; - types_or = ["c" "c++" "java" "json" "objective-c"]; - }; + clang-format = { + enable = true; + types_or = ["c" "c++" "java" "json" "objective-c"]; }; - - tools.clang-tools = pkgs.clang-tools_16; }; + + tools.clang-tools = lib.mkForce pkgs.clang-tools_16; }; devShells.default = pkgs.mkShell { - inherit (self.checks.${system}.pre-commit-check) shellHook; + shellHook = '' + ${config.pre-commit.installationScript} + ''; - inputsFrom = [self.packages.${system}.prismlauncher-unwrapped]; + inputsFrom = [config.packages.pollymc-unwrapped]; buildInputs = with pkgs; [ccache ninja]; }; diff --git a/nix/distribution.nix b/nix/distribution.nix index ce53e0617..2b6cdff2c 100644 --- a/nix/distribution.nix +++ b/nix/distribution.nix @@ -1,30 +1,44 @@ { inputs, self, - version, ... }: { - perSystem = {pkgs, ...}: { - packages = { - inherit (pkgs) pollymc-qt5-unwrapped pollymc-qt5 pollymc-unwrapped pollymc; - default = pkgs.pollymc; + perSystem = { + lib, + pkgs, + ... + }: { + packages = let + ourPackages = lib.fix (final: self.overlays.default ({inherit (pkgs) darwin;} // final) pkgs); + in { + inherit + (ourPackages) + pollymc-qt5-unwrapped + pollymc-qt5 + pollymc-unwrapped + pollymc + ; + default = ourPackages.pollymc; }; }; flake = { overlays.default = final: prev: let - # Helper function to build prism against different versions of Qt. - mkPrism = qt: - qt.callPackage ./package.nix { - inherit (inputs) libnbtplusplus; - inherit (prev.darwin.apple_sdk.frameworks) Cocoa; - inherit self version; - }; + version = builtins.substring 0 8 self.lastModifiedDate or "dirty"; + + # common args for prismlauncher evaluations + unwrappedArgs = { + inherit (inputs) libnbtplusplus; + inherit (final.darwin.apple_sdk.frameworks) Cocoa; + inherit self version; + }; in { - pollymc-qt5-unwrapped = mkPrism final.libsForQt5; - pollymc-qt5 = prev.pollymc-qt5.override {pollymc-unwrapped = final.pollymc-qt5-unwrapped;}; - pollymc-unwrapped = mkPrism final.qt6Packages; - pollymc = prev.pollymc.override {inherit (final) pollymc-unwrapped;}; + pollymc-qt5-unwrapped = prev.libsForQt5.callPackage ./pkg unwrappedArgs; + pollymc-qt5 = prev.libsForQt5.callPackage ./pkg/wrapper.nix { + pollymc-unwrapped = final.pollymc-qt5-unwrapped; + }; + pollymc-unwrapped = prev.qt6Packages.callPackage ./pkg unwrappedArgs; + pollymc = prev.qt6Packages.callPackage ./pkg/wrapper.nix {inherit (final) pollymc-unwrapped;}; }; }; } diff --git a/nix/package.nix b/nix/pkg/default.nix similarity index 100% rename from nix/package.nix rename to nix/pkg/default.nix diff --git a/nix/pkg/wrapper.nix b/nix/pkg/wrapper.nix new file mode 100644 index 000000000..9c92531c4 --- /dev/null +++ b/nix/pkg/wrapper.nix @@ -0,0 +1,91 @@ +{ + lib, + stdenv, + symlinkJoin, + pollymc-unwrapped, + wrapQtAppsHook, + qtbase, # needed for wrapQtAppsHook + qtsvg, + qtwayland, + xorg, + libpulseaudio, + libGL, + glfw, + openal, + jdk8, + jdk17, + gamemode, + flite, + mesa-demos, + udev, + msaClientID ? null, + gamemodeSupport ? stdenv.isLinux, + textToSpeechSupport ? stdenv.isLinux, + jdks ? [jdk17 jdk8], + additionalLibs ? [], + additionalPrograms ? [], +}: let + pollymcFinal = pollymc-unwrapped.override { + inherit msaClientID gamemodeSupport; + }; +in + symlinkJoin { + name = "pollymc-${pollymcFinal.version}"; + + paths = [pollymcFinal]; + + nativeBuildInputs = [ + wrapQtAppsHook + ]; + + buildInputs = + [ + qtbase + qtsvg + ] + ++ lib.optional (lib.versionAtLeast qtbase.version "6" && stdenv.isLinux) qtwayland; + + postBuild = '' + wrapQtAppsHook + ''; + + qtWrapperArgs = let + runtimeLibs = + (with xorg; [ + libX11 + libXext + libXcursor + libXrandr + libXxf86vm + ]) + ++ [ + # lwjgl + libpulseaudio + libGL + glfw + openal + stdenv.cc.cc.lib + + # oshi + udev + ] + ++ lib.optional gamemodeSupport gamemode.lib + ++ lib.optional textToSpeechSupport flite + ++ additionalLibs; + + runtimePrograms = + [ + xorg.xrandr + mesa-demos # need glxinfo + ] + ++ additionalPrograms; + in + ["--prefix pollymc_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}"] + ++ lib.optionals stdenv.isLinux [ + "--set LD_LIBRARY_PATH /run/opengl-driver/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 (pollymcFinal) meta; + } From a9e02ff4d6d313e184bcfedb6d4a8f7e7b0a61d2 Mon Sep 17 00:00:00 2001 From: emanueljg Date: Wed, 6 Sep 2023 21:11:56 +0200 Subject: [PATCH 2/4] fix Nix wrapper using wrong JAVA_PATHS env var --- launcher/java/JavaUtils.cpp | 2 +- nix/pkg/wrapper.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 3512c3079..43624a1e2 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -154,7 +154,7 @@ JavaInstallPtr JavaUtils::GetDefaultJava() QStringList addJavasFromEnv(QList javas) { - auto env = qEnvironmentVariable("PRISMLAUNCHER_JAVA_PATHS"); // FIXME: use launcher name from buildconfig + auto env = qEnvironmentVariable("POLLYMC_JAVA_PATHS"); // FIXME: use launcher name from buildconfig #if defined(Q_OS_WIN32) QList javaPaths = env.replace("\\", "/").split(QLatin1String(";")); diff --git a/nix/pkg/wrapper.nix b/nix/pkg/wrapper.nix index 9c92531c4..a05f3af66 100644 --- a/nix/pkg/wrapper.nix +++ b/nix/pkg/wrapper.nix @@ -80,7 +80,7 @@ in ] ++ additionalPrograms; in - ["--prefix pollymc_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}"] + ["--prefix POLLYMC_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}"] ++ lib.optionals stdenv.isLinux [ "--set LD_LIBRARY_PATH /run/opengl-driver/lib:${lib.makeLibraryPath runtimeLibs}" # xorg.xrandr needed for LWJGL [2.9.2, 3) https://github.com/LWJGL/lwjgl/issues/128 From 79f00f6c50513305d228565f3c341941e1c4ac08 Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Sat, 4 Nov 2023 21:27:55 -0400 Subject: [PATCH 3/4] authlib-injector: link to wiki page with API servers Signed-off-by: Evan Goode --- .../ui/dialogs/AuthlibInjectorLoginDialog.ui | 5 ++++- launcher/ui/pages/global/AccountListPage.cpp | 20 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/launcher/ui/dialogs/AuthlibInjectorLoginDialog.ui b/launcher/ui/dialogs/AuthlibInjectorLoginDialog.ui index 98eb7b89c..b6e157f37 100644 --- a/launcher/ui/dialogs/AuthlibInjectorLoginDialog.ui +++ b/launcher/ui/dialogs/AuthlibInjectorLoginDialog.ui @@ -31,12 +31,15 @@ Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + true + - Email/username + Email/username diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index 3347b8bc5..cd1371527 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -44,9 +44,9 @@ #include "net/NetJob.h" +#include "ui/dialogs/AuthlibInjectorLoginDialog.h" #include "ui/dialogs/CustomMessageBox.h" #include "ui/dialogs/LoginDialog.h" -#include "ui/dialogs/AuthlibInjectorLoginDialog.h" #include "ui/dialogs/MSALoginDialog.h" #include "ui/dialogs/OfflineLoginDialog.h" #include "ui/dialogs/ProgressDialog.h" @@ -156,16 +156,14 @@ void AccountListPage::on_actionAddMojang_triggered() void AccountListPage::on_actionAddAuthlibInjector_triggered() { MinecraftAccountPtr account = AuthlibInjectorLoginDialog::newAccount( - this, - tr( - "Please enter your username (sometimes an email address), password, and the URLs of your API servers." - "

" - "Caution! Your username and password will be sent to the authentication server you specify!" - ) - ); - - if (account) - { + this, tr("Please enter your username (sometimes an email address), password, and the URL of your API server." + "
" + "See this page on the PollyMC wiki for a " + "list of common API servers.

" + "

" + "Caution! Your username and password will be sent to the authentication server you specify!")); + + if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) { m_accounts->setDefaultAccount(account); From b1738deffb3561f0bf783e0a11c4861e50c002a4 Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Sun, 5 Nov 2023 13:46:32 -0500 Subject: [PATCH 4/4] authlib-injector: Mark correct account as in use Fixes a bug where the wrong account could be marked as "in use" when the game is launched if there are multiple accounts that share the same profile ID. This can lead to the launcher trying to refresh an account that's currently in use by the game, leading to "Invalid session" errors in-game. Signed-off-by: Evan Goode --- launcher/minecraft/auth/AccountList.cpp | 11 +++++++++++ launcher/minecraft/auth/AccountList.h | 1 + launcher/minecraft/auth/AuthSession.h | 2 ++ launcher/minecraft/auth/MinecraftAccount.cpp | 2 ++ launcher/minecraft/launch/ClaimAccount.cpp | 2 +- 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 36093a37f..3101c267d 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -79,6 +79,17 @@ int AccountList::findAccountByProfileId(const QString& profileId) const return -1; } +MinecraftAccountPtr AccountList::getAccountByInternalId(const QString& accountId) const +{ + for (int i = 0; i < count(); i++) { + MinecraftAccountPtr account = at(i); + if (account->internalId() == accountId) { + return account; + } + } + return nullptr; +} + MinecraftAccountPtr AccountList::getAccountByProfileName(const QString& profileName) const { for (int i = 0; i < count(); i++) { diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h index 6a0b01916..ccdf25673 100644 --- a/launcher/minecraft/auth/AccountList.h +++ b/launcher/minecraft/auth/AccountList.h @@ -79,6 +79,7 @@ class AccountList : public QAbstractListModel { void addAccount(const MinecraftAccountPtr account); void removeAccount(QModelIndex index); int findAccountByProfileId(const QString& profileId) const; + MinecraftAccountPtr getAccountByInternalId(const QString& accountId) const; MinecraftAccountPtr getAccountByProfileName(const QString& profileName) const; QStringList profileNames() const; diff --git a/launcher/minecraft/auth/AuthSession.h b/launcher/minecraft/auth/AuthSession.h index 6d3fc5e4b..84ecbaac6 100644 --- a/launcher/minecraft/auth/AuthSession.h +++ b/launcher/minecraft/auth/AuthSession.h @@ -33,6 +33,8 @@ struct AuthSession { bool uses_custom_api_servers = false; QString authlib_injector_metadata; + // account ID + QString account_id; // client token QString client_token; // account user name diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index cccde0758..3a1d5cb36 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -328,6 +328,8 @@ void MinecraftAccount::fillSession(AuthSessionPtr session) } } + // account ID + session->account_id = internalId(); // the user name. you have to have an user name // FIXME: not with MSA session->username = data.userName(); diff --git a/launcher/minecraft/launch/ClaimAccount.cpp b/launcher/minecraft/launch/ClaimAccount.cpp index a3de1516a..8c7870b83 100644 --- a/launcher/minecraft/launch/ClaimAccount.cpp +++ b/launcher/minecraft/launch/ClaimAccount.cpp @@ -8,7 +8,7 @@ ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session) : LaunchS { if (session->status == AuthSession::Status::PlayableOnline && !session->demo) { auto accounts = APPLICATION->accounts(); - m_account = accounts->getAccountByProfileName(session->player_name); + m_account = accounts->getAccountByInternalId(session->account_id); } }