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(() -> {