Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle install failures gracefully (and a couple translation changes for path copying) #9

Merged
merged 7 commits into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/main/java/org/quiltmc/installer/CliInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ private static Action<?> parse(String input) {
}

options.put("--no-profile", null);
} else if (option.equals("--copy-profile-path")) {
if (options.containsKey("--copy-profile-path")) {
System.err.println("Encountered duplicate option \"--copy-profile-path\", This shouldn't affect anything");
}

options.put("--copy-profile-path", null);

} else if (option.equals("--disable-beacon")) {
if (options.containsKey("--disable-beacon")) {
System.err.println("Encountered duplicate option \"--disable-beacon\", This shouldn't affect anything");
Expand Down
22 changes: 10 additions & 12 deletions src/main/java/org/quiltmc/installer/action/InstallClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
/**
* An action which installs a new client instance.
*/
public final class InstallClient extends Action<InstallClient.MessageType> {
public final class InstallClient extends Action<InstallMessageType> {
private final String minecraftVersion;
private final LauncherType launcherType;
private final LoaderType loaderType;
Expand All @@ -66,20 +66,20 @@ public final class InstallClient extends Action<InstallClient.MessageType> {
}

@Override
public void run(Consumer<MessageType> statusTracker) {
public void run(Consumer<InstallMessageType> statusTracker) {
switch (this.launcherType) {
case OFFICIAL:
this.installOfficial();
this.installOfficial(statusTracker);
break;
case MULTIMC:
this.installMultimc();
this.installMultimc(statusTracker);
break;
default:
throw new RuntimeException("don't know how to install into " + this.launcherType);
}
}

private void installOfficial() {
private void installOfficial(Consumer<InstallMessageType> statusTracker) {
Path installDir;

if (this.installDir == null) {
Expand Down Expand Up @@ -161,7 +161,7 @@ private void installOfficial() {
throw new UncheckedIOException(e); // Handle via exceptionally
}
}

statusTracker.accept(InstallMessageType.SUCCEED);
println("Completed installation");
} catch (InterruptedException | ExecutionException e) {
// Should not happen since we allOf'd it.
Expand All @@ -171,7 +171,7 @@ private void installOfficial() {
}))).exceptionally(e -> {
eprintln("Failed to install client");
e.printStackTrace();
System.exit(1);
statusTracker.accept(InstallMessageType.FAIL);
return null;
}).join();
}
Expand Down Expand Up @@ -207,7 +207,7 @@ private static void writeLaunchJson(Path path, String json) {
}
}

private void installMultimc() {
private void installMultimc(Consumer<InstallMessageType> statusTracker) {
CompletableFuture<MinecraftInstallation.InstallationInfo> installationInfoFuture = MinecraftInstallation.getInfo(GameSide.CLIENT, this.minecraftVersion, this.loaderType, this.loaderVersion);

installationInfoFuture.thenAccept(installationInfo -> {
Expand All @@ -220,14 +220,12 @@ private void installMultimc() {
installationInfo.manifest(),
this.copyProfilePath
);
statusTracker.accept(InstallMessageType.SUCCEED);
}).exceptionally(e -> {
eprintln("Failed to generate multimc pack");
e.printStackTrace();
System.exit(1);
statusTracker.accept(InstallMessageType.FAIL);
return null;
}).join();
}

public enum MessageType {
}
}
22 changes: 22 additions & 0 deletions src/main/java/org/quiltmc/installer/action/InstallMessageType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2023 QuiltMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.quiltmc.installer.action;

public enum InstallMessageType {
SUCCEED,
FAIL
}
12 changes: 6 additions & 6 deletions src/main/java/org/quiltmc/installer/action/InstallServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
/**
* An action which creates the server launch jar and downloads the dedicated server.
*/
public final class InstallServer extends Action<InstallServer.MessageType> {
public final class InstallServer extends Action<InstallMessageType> {
public static final String SERVICES_DIR = "META-INF/services/";

private final String minecraftVersion;
Expand All @@ -85,7 +85,7 @@ public final class InstallServer extends Action<InstallServer.MessageType> {
}

@Override
public void run(Consumer<MessageType> statusTracker) {
public void run(Consumer<InstallMessageType> statusTracker) {
Path installDir;

if (this.installDir == null) {
Expand Down Expand Up @@ -209,15 +209,18 @@ public void run(Consumer<MessageType> statusTracker) {
// Download Minecraft server and create scripts if specified
if (this.installServer) {
println("Downloading server");
statusTracker.accept(InstallMessageType.SUCCEED);
return downloadServer(installDir, minecraftVersion, installationInfo);
}

statusTracker.accept(InstallMessageType.SUCCEED);
return CompletableFuture.completedFuture(null);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}).exceptionally(e -> {
}).exceptionally(e -> {
e.printStackTrace();
statusTracker.accept(InstallMessageType.FAIL);
return null;
}).join();
}
Expand Down Expand Up @@ -393,7 +396,4 @@ public MinecraftInstallation.InstallationInfo installationInfo() {
public Path installedDir() {
return this.installedDir;
}

public enum MessageType {
}
}
21 changes: 9 additions & 12 deletions src/main/java/org/quiltmc/installer/gui/swing/AbstractPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,11 @@
package org.quiltmc.installer.gui.swing;

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
Expand All @@ -45,6 +36,7 @@
import org.quiltmc.installer.LoaderType;
import org.quiltmc.installer.Localization;
import org.quiltmc.installer.VersionManifest;
import org.quiltmc.installer.action.InstallMessageType;

abstract class AbstractPanel extends JPanel {
final SwingInstaller gui;
Expand Down Expand Up @@ -204,9 +196,14 @@ protected static boolean showPopup(String title, String description, int optionT
return JOptionPane.showOptionDialog(null, pane, title, optionType, messageType, null, null, null) == 0;
}

protected static void showInstalledMessage(LoaderType type) {
showPopup(Localization.get("dialog.install.successful"), Localization.createFrom("dialog.install.successful.description", type.getLocalizedName(), "https://modrinth.com/mod/osl"),
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
protected static void showInstalledMessage(LoaderType type, InstallMessageType msg) {
if (msg == InstallMessageType.SUCCEED) {
showPopup(Localization.get("dialog.install.successful"), Localization.createFrom("dialog.install.successful.description", type.getLocalizedName(), "https://modrinth.com/mod/osl"),
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
} else if (msg == InstallMessageType.FAIL) {
showPopup(Localization.get("dialog.install.failed"), Localization.createFrom("dialog.install.failed.description", type.getLocalizedName()),
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
}
}

private static String buildEditorPaneStyle() {
Expand Down
32 changes: 22 additions & 10 deletions src/main/java/org/quiltmc/installer/gui/swing/ClientPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.awt.event.ItemEvent;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import javax.swing.JButton;
Expand All @@ -34,9 +35,9 @@
import org.jetbrains.annotations.Nullable;
import org.quiltmc.installer.*;
import org.quiltmc.installer.action.Action;
import org.quiltmc.installer.action.InstallClient;
import org.quiltmc.installer.action.InstallMessageType;

final class ClientPanel extends AbstractPanel implements Consumer<InstallClient.MessageType> {
final class ClientPanel extends AbstractPanel implements Consumer<InstallMessageType> {
private final JComboBox<String> minecraftVersionSelector;
private final JComboBox<LauncherLabel> launcherTypeSelector;
private final JComboBox<LoaderLabel> loaderTypeSelector;
Expand Down Expand Up @@ -213,7 +214,7 @@ private void install(ActionEvent event) {
LoaderType loaderType = this.loaderType();
VersionManifest.Version version = this.manifest().getVersion(minecraftVersion);

Action<InstallClient.MessageType> action = Action.installClient(
Action<InstallMessageType> action = Action.installClient(
minecraftVersion,
launcherType,
loaderType,
Expand All @@ -224,18 +225,29 @@ private void install(ActionEvent event) {
this.copyProfilePath
);

action.run(this);
AtomicReference<InstallMessageType> result = new AtomicReference<>();
action.run(result::set);

if (launcherType == LauncherType.MULTIMC) {
showMmcPackGenerationMessage(loaderType);
showMmcPackGenerationMessage(loaderType, this.copyProfilePath, result.get());
} else {
showInstalledMessage(loaderType);
showInstalledMessage(loaderType, result.get());
}
}

private static void showMmcPackGenerationMessage(LoaderType type){
showPopup(Localization.get("dialog.install.mmc.successful"), Localization.createFrom("dialog.install.mmc.successful.description", type.getLocalizedName(), "https://modrinth.com/mod/osl"),
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
private static void showMmcPackGenerationMessage(LoaderType type, boolean copyProfilePath, InstallMessageType msg) {
if (msg == InstallMessageType.SUCCEED) {
showPopup(
Localization.get("dialog.install.mmc.successful"),
Localization.createFrom("dialog.install.mmc.successful.description",
type.getLocalizedName(),
"https://modrinth.com/mod/osl",
copyProfilePath ? " " + Localization.get("dialog.install.mmc.copy-path") : ""
),
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
} else if (msg == InstallMessageType.FAIL) {
showPopup(Localization.get("dialog.install.mmc.failed"), Localization.get("dialog.install.mmc.failed"), JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
}
}

LauncherType launcherType() {
Expand All @@ -261,7 +273,7 @@ void receiveVersions(VersionManifest manifest, Map<LoaderType, List<String>> loa
}

@Override
public void accept(InstallClient.MessageType messageType) {
public void accept(InstallMessageType messageType) {
}

class LauncherLabel extends JLabel {
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/org/quiltmc/installer/gui/swing/ServerPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import javax.swing.*;
Expand All @@ -34,10 +35,11 @@
import org.quiltmc.installer.Localization;
import org.quiltmc.installer.VersionManifest;
import org.quiltmc.installer.action.Action;
import org.quiltmc.installer.action.InstallMessageType;
import org.quiltmc.installer.action.InstallServer;
import org.quiltmc.parsers.json.JsonReader;

final class ServerPanel extends AbstractPanel implements Consumer<InstallServer.MessageType> {
final class ServerPanel extends AbstractPanel implements Consumer<InstallMessageType> {
private final JComboBox<String> minecraftVersionSelector;
private final JComboBox<LoaderLabel> loaderTypeSelector;
private final JComboBox<String> loaderVersionSelector;
Expand Down Expand Up @@ -224,9 +226,9 @@ private void install(ActionEvent event) {
this.downloadServer
);

action.run(this);

showInstalledMessage(loaderType);
AtomicReference<InstallMessageType> result = new AtomicReference<>();
action.run(result::set);
showInstalledMessage(loaderType, result.get());
}

private void updateFlags() {
Expand Down Expand Up @@ -255,6 +257,6 @@ private void updateFlags() {
}

@Override
public void accept(InstallServer.MessageType messageType) {
public void accept(InstallMessageType messageType) {
}
}
2 changes: 2 additions & 0 deletions src/main/resources/lang/en-US.usage
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ where install options for only the client also include:
Causes the installer to not generate a new profile.
--disable-beacon
Prevents you from counting towards the monthly user statistics
--copy-profile-path
Copies the profile path to the clipboard if generating a MultiMC instance

where install options for only the server also include:

Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/lang/installer.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ gui.install.mmc=Generate Pack
dialog.install.successful=Successfully Installed
dialog.install.mmc.successful=Successful
dialog.install.successful.description={0} Loader has been successfully installed.<br>Most mods require that you also download the <a href="{1}">Ornithe Standard Libraries</a> mod and place it in your mods folder</br>
dialog.install.mmc.successful.description=A Mmc/PrismLauncher pack has been generated with {0} Loader and copied to the clipboard.<br>Most mods require that you also download the <a href="{1}">Ornithe Standard Libraries</a> mod and place it in your mods folder</br>
dialog.install.mmc.successful.description=A Mmc/PrismLauncher pack has been generated with {0} Loader{2}.<br>Most mods require that you also download the <a href="{1}">Ornithe Standard Libraries</a> mod and place it in your mods folder</br>.
dialog.install.mmc.copy-path=and copied to the clipboard
dialog.install.failed=Failed to Install
dialog.install.mmc.failed=Failed to Generate Pack
dialog.install.failed.description={0} Loader failed to be installed.

dialog.install.server.overwrite-jar=Overwrite Minecraft Jar
dialog.install.server.overwrite-jar.description=You already have a valid Minecraft jar file.<br>Are you sure you want to overwrite it?<br>This will not affect your world save or any other files.
Expand Down
Loading