From 567bd1599724532a6687b861d5ac0e79091a6131 Mon Sep 17 00:00:00 2001 From: Glavo Date: Thu, 18 Dec 2025 21:18:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E9=99=B6=E7=93=A6=E8=81=94=E6=9C=BA?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=90=AF=E5=8A=A8=E6=B8=B8=E6=88=8F=E6=97=B6?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E7=A6=BB=E7=BA=BF=E7=9A=AE=E8=82=A4=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20(#4916)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmcl/game/HMCLGameRepository.java | 4 ++-- .../jackhuang/hmcl/game/LauncherHelper.java | 19 ++++++++++++++++--- .../terracotta/TerracottaControllerPage.java | 5 ++++- .../hmcl/ui/terracotta/TerracottaPage.java | 6 ++++-- .../hmcl/auth/offline/OfflineAccount.java | 8 ++++++-- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index 87eac5d85..fa3f43206 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -387,7 +387,7 @@ public final class HMCLGameRepository extends DefaultGameRepository { vs.setUsesGlobal(true); } - public LaunchOptions getLaunchOptions(String version, JavaRuntime javaVersion, Path gameDir, List javaAgents, List javaArguments, boolean makeLaunchScript) { + public LaunchOptions.Builder getLaunchOptions(String version, JavaRuntime javaVersion, Path gameDir, List javaAgents, List javaArguments, boolean makeLaunchScript) { VersionSetting vs = getVersionSetting(version); LaunchOptions.Builder builder = new LaunchOptions.Builder() @@ -461,7 +461,7 @@ public final class HMCLGameRepository extends DefaultGameRepository { if (vs.isAutoMemory() && builder.getJavaArguments().stream().anyMatch(it -> it.startsWith("-Xmx"))) builder.setMaxMemory(null); - return builder.create(); + return builder; } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 54a547f83..51ed1d5de 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -22,6 +22,7 @@ import javafx.stage.Stage; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.auth.*; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDownloadException; +import org.jackhuang.hmcl.auth.offline.OfflineAccount; import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.LibraryAnalyzer; @@ -81,6 +82,7 @@ public final class LauncherHelper { private final VersionSetting setting; private LauncherVisibility launcherVisibility; private boolean showLogs; + private boolean disableOfflineSkin = false; public LauncherHelper(Profile profile, Account account, String selectedVersion) { this.profile = Objects.requireNonNull(profile); @@ -111,6 +113,10 @@ public final class LauncherHelper { launcherVisibility = LauncherVisibility.KEEP; } + public void setDisableOfflineSkin() { + disableOfflineSkin = true; + } + public void launch() { FXUtils.checkFxUserThread(); @@ -188,8 +194,12 @@ public final class LauncherHelper { .thenComposeAsync(() -> gameVersion.map(s -> new GameVerificationFixTask(dependencyManager, s, version.get())).orElse(null)) .thenComposeAsync(() -> logIn(account).withStage("launch.state.logging_in")) .thenComposeAsync(authInfo -> Task.supplyAsync(() -> { - LaunchOptions launchOptions = repository.getLaunchOptions( + LaunchOptions.Builder launchOptionsBuilder = repository.getLaunchOptions( selectedVersion, javaVersionRef.get(), profile.getGameDir(), javaAgents, javaArguments, scriptFile != null); + if (disableOfflineSkin) { + launchOptionsBuilder.setDaemon(false); + } + LaunchOptions launchOptions = launchOptionsBuilder.create(); LOG.info("Here's the structure of game mod directory:\n" + FileUtils.printFileStructure(repository.getModsDirectory(selectedVersion), 10)); @@ -639,10 +649,13 @@ public final class LauncherHelper { return future; } - private static Task logIn(Account account) { + private Task logIn(Account account) { return Task.composeAsync(() -> { try { - return Task.completed(account.logIn()); + if (disableOfflineSkin && account instanceof OfflineAccount offlineAccount) + return Task.completed(offlineAccount.logInWithoutSkin()); + else + return Task.completed(account.logIn()); } catch (CredentialExpiredException e) { LOG.info("Credential has expired", e); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaControllerPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaControllerPage.java index 4496addbc..0b17342e5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaControllerPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaControllerPage.java @@ -232,7 +232,10 @@ public class TerracottaControllerPage extends StackPane { MessageDialogPane.MessageType.QUESTION ).addAction(i18n("version.launch"), () -> { Profile profile = Profiles.getSelectedProfile(); - Versions.launch(profile, profile.getSelectedVersion(), LauncherHelper::setKeep); + Versions.launch(profile, profile.getSelectedVersion(), launcherHelper -> { + launcherHelper.setKeep(); + launcherHelper.setDisableOfflineSkin(); + }); }).addCancel(i18n("terracotta.status.waiting.host.launch.skip"), () -> { TerracottaState.HostScanning s1 = TerracottaManager.setScanning(); if (s1 != null) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaPage.java index ff8f2af4b..3f94c7d82 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaPage.java @@ -24,7 +24,6 @@ import javafx.geometry.Insets; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; -import org.jackhuang.hmcl.game.LauncherHelper; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.terracotta.TerracottaMetadata; @@ -71,7 +70,10 @@ public class TerracottaPage extends DecoratorAnimatedPage implements DecoratorPa AdvancedListBox toolbar = new AdvancedListBox() .addNavigationDrawerItem(i18n("version.launch"), SVG.ROCKET_LAUNCH, () -> { Profile profile = Profiles.getSelectedProfile(); - Versions.launch(profile, profile.getSelectedVersion(), LauncherHelper::setKeep); + Versions.launch(profile, profile.getSelectedVersion(), launcherHelper -> { + launcherHelper.setKeep(); + launcherHelper.setDisableOfflineSkin(); + }); }, item -> { instanceChangeListenerHolder = FXUtils.onWeakChangeAndOperate(Profiles.selectedVersionProperty(), instanceName -> item.setSubtitle(StringUtils.isNotBlank(instanceName) ? instanceName : i18n("version.empty")) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java index e6955b745..7e93fa901 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/OfflineAccount.java @@ -103,10 +103,14 @@ public class OfflineAccount extends Account { return skin != null && skin.getType() != Skin.Type.DEFAULT; } + public AuthInfo logInWithoutSkin() throws AuthenticationException { + // Using "legacy" user type here because "mojang" user type may cause "invalid session token" or "disconnected" when connecting to a game server. + return new AuthInfo(username, uuid, UUIDTypeAdapter.fromUUID(UUID.randomUUID()), AuthInfo.USER_TYPE_MSA, "{}"); + } + @Override public AuthInfo logIn() throws AuthenticationException { - // Using "legacy" user type here because "mojang" user type may cause "invalid session token" or "disconnected" when connecting to a game server. - AuthInfo authInfo = new AuthInfo(username, uuid, UUIDTypeAdapter.fromUUID(UUID.randomUUID()), AuthInfo.USER_TYPE_MSA, "{}"); + AuthInfo authInfo = logInWithoutSkin(); if (loadAuthlibInjector(skin)) { CompletableFuture artifactTask = CompletableFuture.supplyAsync(() -> {