196 lines
8.8 KiB
Java
196 lines
8.8 KiB
Java
package io.gitlab.jfronny.inceptum.gtk;
|
|
|
|
import io.gitlab.jfronny.commons.io.JFiles;
|
|
import io.gitlab.jfronny.inceptum.common.MetaHolder;
|
|
import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog;
|
|
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog;
|
|
import io.gitlab.jfronny.inceptum.gtk.window.settings.launcher.LauncherSettingsWindow;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.importer.Importers;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.launch.*;
|
|
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
|
|
import org.gtk.gio.Menu;
|
|
import org.gtk.gtk.*;
|
|
import io.gitlab.jfronny.commons.ref.R;
|
|
import io.gitlab.jfronny.inceptum.common.Utils;
|
|
import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder;
|
|
import io.gitlab.jfronny.inceptum.gtk.util.I18n;
|
|
import io.gitlab.jfronny.inceptum.gtk.window.AboutWindow;
|
|
import io.gitlab.jfronny.inceptum.gtk.window.NewInstanceWindow;
|
|
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
|
|
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager;
|
|
import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
|
|
|
|
import java.awt.*;
|
|
import java.awt.datatransfer.DataFlavor;
|
|
import java.io.IOException;
|
|
import java.nio.file.Path;
|
|
import java.util.*;
|
|
import java.util.List;
|
|
|
|
public class GtkMenubar {
|
|
public static MenuBuilder newMenu;
|
|
public static MenuBuilder accountsMenu;
|
|
public static MenuBuilder launchMenu;
|
|
|
|
public static void create(Application app) {
|
|
var menu = new MenuBuilder(app);
|
|
var file = menu.submenu("file");
|
|
newMenu = file.submenu("new");
|
|
generateNewMenu(app);
|
|
file.button("redownload", () -> {
|
|
ProcessState state = new ProcessState(3 + Steps.STEPS.size() * InstanceList.size(), "Initializing");
|
|
ProcessStateWatcherDialog.show(
|
|
GtkEnvBackend.INSTANCE.dialogParent,
|
|
"Reloading data",
|
|
"Could not execute refresh task",
|
|
state,
|
|
() -> {
|
|
state.incrementStep("Clearing cache directories");
|
|
JFiles.clearDirectory(MetaHolder.ASSETS_DIR);
|
|
JFiles.clearDirectory(MetaHolder.LIBRARIES_DIR, path -> !path.startsWith(MetaHolder.LIBRARIES_DIR.resolve("io/gitlab/jfronny")));
|
|
JFiles.clearDirectory(MetaHolder.NATIVES_DIR, path -> !path.startsWith(MetaHolder.NATIVES_DIR.resolve("forceload")));
|
|
JFiles.clearDirectory(MetaHolder.CACHE_DIR);
|
|
if (state.isCancelled) return;
|
|
state.incrementStep("Reloading instance list");
|
|
InstanceList.reset();
|
|
InstanceList.forEach(instance -> {
|
|
if (state.isCancelled) return;
|
|
Steps.reDownload(instance, state);
|
|
});
|
|
});
|
|
});
|
|
file.button("exit", app::quit);
|
|
launchMenu = menu.submenu("launch");
|
|
generateLaunchMenu(app);
|
|
accountsMenu = menu.submenu("account");
|
|
generateAccountsMenu(app);
|
|
var help = menu.submenu("help");
|
|
help.button("about", AboutWindow::createAndShow);
|
|
help.button("log", () -> {
|
|
//TODO
|
|
});
|
|
}
|
|
|
|
public static void generateNewMenu(Application app) {
|
|
Objects.requireNonNull(newMenu).clear();
|
|
newMenu.button("new", () -> new NewInstanceWindow(app).show());
|
|
newMenu.button("file", () -> {
|
|
FileChooserNative dialog = new FileChooserNative(
|
|
I18n.get("menu.file.new.file"),
|
|
GtkEnvBackend.INSTANCE.dialogParent,
|
|
FileChooserAction.OPEN,
|
|
"_" + I18n.get("select"),
|
|
"_" + I18n.get("cancel")
|
|
);
|
|
var filter = new FileFilter();
|
|
filter.addPattern("*.zip");
|
|
filter.addPattern("*.mrpack");
|
|
dialog.addFilter(filter);
|
|
dialog.onResponse(responseId -> {
|
|
if (responseId == ResponseType.ACCEPT.value) {
|
|
var file = dialog.file.path;
|
|
if (file == null) {
|
|
LauncherEnv.showError("The path returned by the file dialog is null", "Could not import");
|
|
return;
|
|
}
|
|
ProcessState state = new ProcessState(Importers.MAX_STEPS, "Initializing");
|
|
ProcessStateWatcherDialog.show(
|
|
GtkEnvBackend.INSTANCE.dialogParent,
|
|
I18n.get("menu.file.new.file"),
|
|
I18n.get("menu.file.new.file.error"),
|
|
state,
|
|
() -> Importers.importPack(Path.of(file), state)
|
|
);
|
|
}
|
|
});
|
|
dialog.show();
|
|
});
|
|
newMenu.button("url", () -> {
|
|
LauncherEnv.getInput(
|
|
I18n.get("menu.file.new.url"),
|
|
I18n.get("menu.file.new.url.details"),
|
|
(String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor),
|
|
s -> {
|
|
ProcessState state = new ProcessState(Importers.MAX_STEPS, "Initializing");
|
|
ProcessStateWatcherDialog.show(
|
|
GtkEnvBackend.INSTANCE.dialogParent,
|
|
I18n.get("menu.file.new.url"),
|
|
I18n.get("menu.file.new.url.error"),
|
|
state,
|
|
() -> Importers.importPack(s, state)
|
|
);
|
|
},
|
|
R::nop
|
|
);
|
|
});
|
|
}
|
|
|
|
public static void generateLaunchMenu(Application app) {
|
|
Objects.requireNonNull(launchMenu).clear();
|
|
try {
|
|
InstanceList.forEach(entry -> {
|
|
launchMenu.literalButton(entry.id() + ".launch", entry.toString(), () -> launch(entry, LaunchType.Client));
|
|
});
|
|
} catch (IOException e) {
|
|
Utils.LOGGER.error("Could not generate launch menu", e);
|
|
}
|
|
}
|
|
|
|
public static void launch(Instance instance, LaunchType launchType) {
|
|
if (instance.isSetupLocked) {
|
|
LauncherEnv.showError(I18n.get("instance.launch.locked.setup"), I18n.get("instance.launch.locked"));
|
|
} else if (instance.isRunningLocked) {
|
|
LauncherEnv.showOkCancel(
|
|
I18n.get("instance.launch.locked.running"),
|
|
I18n.get("instance.launch.locked"),
|
|
() -> forceLaunch(instance, launchType),
|
|
R::nop
|
|
);
|
|
} else forceLaunch(instance, launchType);
|
|
}
|
|
|
|
private static void forceLaunch(Instance instance, LaunchType launchType) {
|
|
ProcessState state = Steps.createProcessState();
|
|
ProcessStateWatcherDialog.show(
|
|
GtkEnvBackend.INSTANCE.dialogParent,
|
|
I18n.get("instance.launch.title"),
|
|
I18n.get("instance.launch.error"),
|
|
state,
|
|
() -> {
|
|
try {
|
|
Steps.reDownload(instance, state);
|
|
} catch (IOException e) {
|
|
Utils.LOGGER.error("Could not fetch instance, trying to start anyways", e);
|
|
}
|
|
if (state.isCancelled) return;
|
|
state.updateStep("Starting Game");
|
|
try {
|
|
if (launchType == LaunchType.Client) InstanceLauncher.launchClient(instance);
|
|
else InstanceLauncher.launch(instance, launchType, false, AccountManager.NULL_AUTH);
|
|
} catch (Throwable e) {
|
|
LauncherEnv.showError("Could not start instance", e);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
public static void generateAccountsMenu(Application app) {
|
|
Objects.requireNonNull(accountsMenu).clear();
|
|
accountsMenu.button("new", () -> new MicrosoftLoginDialog(GtkEnvBackend.INSTANCE.dialogParent).show());
|
|
accountsMenu.button("manage", () -> {
|
|
var window = new LauncherSettingsWindow(app);
|
|
window.activePage = "settings.accounts";
|
|
window.show();
|
|
});
|
|
List<MicrosoftAccount> accounts = new ArrayList<>(AccountManager.accounts);
|
|
accounts.add(null);
|
|
accountsMenu.literalRadio("account", accounts.get(AccountManager.selectedIndex), accounts, (i, acc) -> {
|
|
if (acc == null) return I18n.get("account.none");
|
|
return acc.minecraftUsername;
|
|
}, AccountManager::switchAccount);
|
|
}
|
|
}
|