1
0
mirror of https://github.com/SKCraft/Launcher.git synced 2024-11-23 12:05:44 +01:00

GH-472 Add warning popup for mismatched Java versions

Closes #472
This commit is contained in:
Henry Le Grys 2022-05-30 20:58:40 +01:00
parent b8a6769c43
commit 1c64de1df0
4 changed files with 76 additions and 6 deletions

View File

@ -16,11 +16,14 @@ import com.skcraft.launcher.auth.Session;
import com.skcraft.launcher.dialog.AccountSelectDialog;
import com.skcraft.launcher.dialog.ProgressDialog;
import com.skcraft.launcher.launch.LaunchOptions.UpdatePolicy;
import com.skcraft.launcher.launch.runtime.JavaRuntime;
import com.skcraft.launcher.model.minecraft.JavaVersion;
import com.skcraft.launcher.persistence.Persistence;
import com.skcraft.launcher.swing.SwingHelper;
import com.skcraft.launcher.update.Updater;
import com.skcraft.launcher.util.SharedLocale;
import com.skcraft.launcher.util.SwingExecutor;
import lombok.RequiredArgsConstructor;
import lombok.extern.java.Log;
import org.apache.commons.io.FileUtils;
@ -29,6 +32,8 @@ import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.function.BiPredicate;
import java.util.logging.Level;
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
@ -119,7 +124,7 @@ public class LaunchSupervisor {
final File extractDir = launcher.createExtractDir();
// Get the process
Runner task = new Runner(launcher, instance, session, extractDir);
Runner task = new Runner(launcher, instance, session, extractDir, new RuntimeVerifier(instance));
ObservableFuture<Process> processFuture = new ObservableFuture<Process>(
launcher.getExecutor().submit(task), task);
@ -169,4 +174,38 @@ public class LaunchSupervisor {
}
}, sameThreadExecutor());
}
@RequiredArgsConstructor
static class RuntimeVerifier implements BiPredicate<JavaRuntime, JavaVersion> {
private final Instance instance;
@Override
public boolean test(JavaRuntime javaRuntime, JavaVersion javaVersion) {
ListenableFuture<Boolean> fut = SwingExecutor.INSTANCE.submit(() -> {
Object[] options = new Object[]{
tr("button.cancel"),
tr("button.launchAnyway"),
};
String message = tr("runner.wrongJavaVersion",
instance.getTitle(), javaVersion.getMajorVersion(), javaRuntime.getVersion());
int picked = JOptionPane.showOptionDialog(null,
SwingHelper.htmlWrap(message),
tr("launcher.javaMismatchTitle"),
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
null);
return picked == 1;
});
try {
return fut.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@ -37,6 +37,8 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.function.BiPredicate;
import static com.skcraft.launcher.LauncherUtils.checkInterrupted;
import static com.skcraft.launcher.util.SharedLocale.tr;
@ -54,6 +56,7 @@ public class Runner implements Callable<Process>, ProgressObservable {
private final Instance instance;
private final Session session;
private final File extractDir;
private final BiPredicate<JavaRuntime, JavaVersion> javaRuntimeMismatch;
@Getter @Setter private Environment environment = Environment.getInstance();
private VersionManifest versionManifest;
@ -66,18 +69,20 @@ public class Runner implements Callable<Process>, ProgressObservable {
/**
* Create a new instance launcher.
*
* @param launcher the launcher
* @param instance the instance
* @param session the session
* @param extractDir the directory to extract to
* @param javaRuntimeMismatch
*/
public Runner(@NonNull Launcher launcher, @NonNull Instance instance,
@NonNull Session session, @NonNull File extractDir) {
@NonNull Session session, @NonNull File extractDir,
BiPredicate<JavaRuntime, JavaVersion> javaRuntimeMismatch) {
this.launcher = launcher;
this.instance = instance;
this.session = session;
this.extractDir = extractDir;
this.javaRuntimeMismatch = javaRuntimeMismatch;
this.featureList = new FeatureList.Mutable();
}
@ -149,6 +154,8 @@ public class Runner implements Callable<Process>, ProgressObservable {
callLaunchModifier();
verifyJavaRuntime();
ProcessBuilder processBuilder = new ProcessBuilder(builder.buildCommand());
processBuilder.directory(instance.getContentDir());
Runner.log.info("Launching: " + builder);
@ -166,6 +173,23 @@ public class Runner implements Callable<Process>, ProgressObservable {
instance.modify(builder);
}
private void verifyJavaRuntime() {
JavaRuntime pickedRuntime = builder.getRuntime();
JavaVersion targetVersion = versionManifest.getJavaVersion();
if (pickedRuntime == null || targetVersion == null) {
return;
}
if (pickedRuntime.getMajorVersion() != targetVersion.getMajorVersion()) {
boolean launchAnyway = javaRuntimeMismatch.test(pickedRuntime, targetVersion);
if (!launchAnyway) {
throw new CancellationException("Launch cancelled by user.");
}
}
}
/**
* Add platform-specific arguments.
*/

View File

@ -70,6 +70,11 @@ public final class SwingHelper {
.replace("&", "&amp;");
}
public static String htmlWrap(String message) {
// To force the label to wrap, convert the message to broken HTML
return "<html><div style=\"width: 250px\">" + htmlEscape(message);
}
public static void setClipboard(String text) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(text), clipboardOwner);
@ -189,8 +194,7 @@ public final class SwingHelper {
final int messageType) {
if (SwingUtilities.isEventDispatchThread()) {
// To force the label to wrap, convert the message to broken HTML
String htmlMessage = "<html><div style=\"width: 250px\">" + htmlEscape(message);
String htmlMessage = htmlWrap(message);
JPanel panel = new JPanel(new BorderLayout(0, detailsText != null ? 20 : 0));

View File

@ -23,6 +23,7 @@ errors.selfUpdateCheckError=Checking for an update to the launcher has failed.
button.cancel=Cancel
button.ok=OK
button.save=Save
button.launchAnyway=Launch Anyway
options.title = Options
options.useProxyCheck = Use following proxy in Minecraft
@ -88,6 +89,7 @@ launcher.noInstanceError=Please select a modpack to launch.
launcher.noInstanceTitle=No Modpack Selected
launcher.launchingTItle=Launching the game...
launcher.launchingStatus=Launching ''{0}''. Please wait.
launcher.javaMismatchTitle=Java version warning
launcher.modpackColumn=Modpack
launcher.notInstalledHint=(not installed)
launcher.requiresUpdateHint=(requires update)
@ -191,6 +193,7 @@ runner.updateRequired=This instance must be updated before it can be run.
runner.missingLibrary={0} needs to be relaunched and updated because the library ''{1}'' is missing.
runner.missingAssetsIndex={0} needs to be relaunched and updated because its asset index is missing.
runner.corruptAssetsIndex={0} needs to be relaunched and updated because its asset index is corrupt.
runner.wrongJavaVersion=Instance ''{0}'' requires Java version {1}, but could only find {2}.
assets.expanding1=Expanding {0} asset... ({1} remaining)
assets.expandingN=Expanding {0} assets... ({1} remaining)