Add test game in game list page
This commit is contained in:
@@ -40,7 +40,10 @@ import org.jackhuang.hmcl.ui.LogWindow;
|
|||||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
import org.jackhuang.hmcl.ui.construct.MessageBox;
|
||||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.Log4jLevel;
|
||||||
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
|
import org.jackhuang.hmcl.util.Pair;
|
||||||
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
|
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
|
||||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||||
import org.jackhuang.hmcl.util.platform.CommandBuilder;
|
import org.jackhuang.hmcl.util.platform.CommandBuilder;
|
||||||
@@ -62,39 +65,58 @@ import static org.jackhuang.hmcl.util.Pair.pair;
|
|||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
public final class LauncherHelper {
|
public final class LauncherHelper {
|
||||||
public static final LauncherHelper INSTANCE = new LauncherHelper();
|
|
||||||
private LauncherHelper(){}
|
|
||||||
|
|
||||||
public static final Queue<ManagedProcess> PROCESSES = new ConcurrentLinkedQueue<>();
|
private final Profile profile;
|
||||||
|
private final Account account;
|
||||||
|
private final String selectedVersion;
|
||||||
|
private File scriptFile;
|
||||||
|
private final VersionSetting setting;
|
||||||
|
private LauncherVisibility launcherVisibility;
|
||||||
|
private boolean showLogs;
|
||||||
|
|
||||||
|
public LauncherHelper(Profile profile, Account account, String selectedVersion) {
|
||||||
|
this.profile = Objects.requireNonNull(profile);
|
||||||
|
this.account = Objects.requireNonNull(account);
|
||||||
|
this.selectedVersion = Objects.requireNonNull(selectedVersion);
|
||||||
|
this.setting = profile.getVersionSetting(selectedVersion);
|
||||||
|
this.launcherVisibility = setting.getLauncherVisibility();
|
||||||
|
this.showLogs = setting.isShowLogs();
|
||||||
|
}
|
||||||
|
|
||||||
private final TaskExecutorDialogPane launchingStepsPane = new TaskExecutorDialogPane(it -> {});
|
private final TaskExecutorDialogPane launchingStepsPane = new TaskExecutorDialogPane(it -> {});
|
||||||
|
|
||||||
public void launch(Profile profile, Account account, String selectedVersion, File scriptFile) {
|
public void setTestMode() {
|
||||||
if (account == null)
|
launcherVisibility = LauncherVisibility.KEEP;
|
||||||
throw new IllegalArgumentException("No account");
|
showLogs = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void launch() {
|
||||||
Logging.LOG.info("Launching game version: " + selectedVersion);
|
Logging.LOG.info("Launching game version: " + selectedVersion);
|
||||||
|
|
||||||
GameRepository repository = profile.getRepository();
|
GameRepository repository = profile.getRepository();
|
||||||
|
|
||||||
Version version = repository.getResolvedVersion(selectedVersion);
|
Version version = repository.getResolvedVersion(selectedVersion);
|
||||||
VersionSetting setting = profile.getVersionSetting(selectedVersion);
|
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
try {
|
try {
|
||||||
checkGameState(profile, setting, version, () -> {
|
checkGameState(profile, setting, version, () -> {
|
||||||
Controllers.dialog(launchingStepsPane);
|
Controllers.dialog(launchingStepsPane);
|
||||||
Schedulers.newThread().schedule(() -> launch0(profile, account, selectedVersion, scriptFile));
|
Schedulers.newThread().schedule(this::launch0);
|
||||||
});
|
});
|
||||||
} catch (InterruptedException ignore) {
|
} catch (InterruptedException ignore) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launch0(Profile profile, Account account, String selectedVersion, File scriptFile) {
|
public void makeLaunchScript(File scriptFile) {
|
||||||
|
this.scriptFile = Objects.requireNonNull(scriptFile);
|
||||||
|
|
||||||
|
launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launch0() {
|
||||||
HMCLGameRepository repository = profile.getRepository();
|
HMCLGameRepository repository = profile.getRepository();
|
||||||
DefaultDependencyManager dependencyManager = profile.getDependency();
|
DefaultDependencyManager dependencyManager = profile.getDependency();
|
||||||
Version version = MaintainTask.maintain(repository.getResolvedVersion(selectedVersion));
|
Version version = MaintainTask.maintain(repository.getResolvedVersion(selectedVersion));
|
||||||
VersionSetting setting = profile.getVersionSetting(selectedVersion);
|
|
||||||
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||||
|
|
||||||
TaskExecutor executor = Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.DEPENDENCIES))
|
TaskExecutor executor = Task.of(Schedulers.javafx(), () -> emitStatus(LoadingState.DEPENDENCIES))
|
||||||
@@ -134,7 +156,7 @@ public final class LauncherHelper {
|
|||||||
selectedVersion,
|
selectedVersion,
|
||||||
variables.get("account"),
|
variables.get("account"),
|
||||||
setting.toLaunchOptions(profile.getGameDir()),
|
setting.toLaunchOptions(profile.getGameDir()),
|
||||||
setting.getLauncherVisibility() == LauncherVisibility.CLOSE
|
launcherVisibility == LauncherVisibility.CLOSE
|
||||||
? null // Unnecessary to start listening to game process output when close launcher immediately after game launched.
|
? null // Unnecessary to start listening to game process output when close launcher immediately after game launched.
|
||||||
: new HMCLProcessListener(variables.get("account"), setting, gameVersion.isPresent())
|
: new HMCLProcessListener(variables.get("account"), setting, gameVersion.isPresent())
|
||||||
));
|
));
|
||||||
@@ -154,7 +176,7 @@ public final class LauncherHelper {
|
|||||||
if (scriptFile == null) {
|
if (scriptFile == null) {
|
||||||
ManagedProcess process = variables.get(LaunchTask.LAUNCH_ID);
|
ManagedProcess process = variables.get(LaunchTask.LAUNCH_ID);
|
||||||
PROCESSES.add(process);
|
PROCESSES.add(process);
|
||||||
if (setting.getLauncherVisibility() == LauncherVisibility.CLOSE)
|
if (launcherVisibility == LauncherVisibility.CLOSE)
|
||||||
Launcher.stopApplication();
|
Launcher.stopApplication();
|
||||||
else
|
else
|
||||||
launchingStepsPane.setCancel(it -> {
|
launchingStepsPane.setCancel(it -> {
|
||||||
@@ -337,11 +359,6 @@ public final class LauncherHelper {
|
|||||||
onAccept.run();
|
onAccept.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void stopManagedProcesses() {
|
|
||||||
while (!PROCESSES.isEmpty())
|
|
||||||
Optional.ofNullable(PROCESSES.poll()).ifPresent(ManagedProcess::stop);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void emitStatus(LoadingState state) {
|
public void emitStatus(LoadingState state) {
|
||||||
if (state == LoadingState.DONE) {
|
if (state == LoadingState.DONE) {
|
||||||
launchingStepsPane.fireEvent(new DialogCloseEvent());
|
launchingStepsPane.fireEvent(new DialogCloseEvent());
|
||||||
@@ -351,8 +368,8 @@ public final class LauncherHelper {
|
|||||||
launchingStepsPane.setSubtitle((state.ordinal() + 1) + " / " + LoadingState.values().length);
|
launchingStepsPane.setSubtitle((state.ordinal() + 1) + " / " + LoadingState.values().length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkExit(LauncherVisibility v) {
|
private void checkExit() {
|
||||||
switch (v) {
|
switch (launcherVisibility) {
|
||||||
case HIDE_AND_REOPEN:
|
case HIDE_AND_REOPEN:
|
||||||
Platform.runLater(Controllers.getStage()::show);
|
Platform.runLater(Controllers.getStage()::show);
|
||||||
break;
|
break;
|
||||||
@@ -401,7 +418,6 @@ public final class LauncherHelper {
|
|||||||
|
|
||||||
private final VersionSetting setting;
|
private final VersionSetting setting;
|
||||||
private final Map<String, String> forbiddenTokens;
|
private final Map<String, String> forbiddenTokens;
|
||||||
private final LauncherVisibility visibility;
|
|
||||||
private ManagedProcess process;
|
private ManagedProcess process;
|
||||||
private boolean lwjgl;
|
private boolean lwjgl;
|
||||||
private LogWindow logWindow;
|
private LogWindow logWindow;
|
||||||
@@ -422,7 +438,6 @@ public final class LauncherHelper {
|
|||||||
pair(authInfo.getUsername(), "<player>")
|
pair(authInfo.getUsername(), "<player>")
|
||||||
);
|
);
|
||||||
|
|
||||||
visibility = setting.getLauncherVisibility();
|
|
||||||
logs = new LinkedList<>();
|
logs = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +445,7 @@ public final class LauncherHelper {
|
|||||||
public void setProcess(ManagedProcess process) {
|
public void setProcess(ManagedProcess process) {
|
||||||
this.process = process;
|
this.process = process;
|
||||||
|
|
||||||
if (setting.isShowLogs())
|
if (showLogs)
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
logWindow = new LogWindow();
|
logWindow = new LogWindow();
|
||||||
logWindow.show();
|
logWindow.show();
|
||||||
@@ -453,7 +468,7 @@ public final class LauncherHelper {
|
|||||||
if (logs.size() > config().getLogLines())
|
if (logs.size() > config().getLogLines())
|
||||||
logs.removeFirst();
|
logs.removeFirst();
|
||||||
|
|
||||||
if (setting.isShowLogs()) {
|
if (showLogs) {
|
||||||
try {
|
try {
|
||||||
latch.await();
|
latch.await();
|
||||||
logWindow.waitForLoaded();
|
logWindow.waitForLoaded();
|
||||||
@@ -467,7 +482,7 @@ public final class LauncherHelper {
|
|||||||
|
|
||||||
if (!lwjgl && (log.contains("LWJGL Version: ") || !detectWindow)) {
|
if (!lwjgl && (log.contains("LWJGL Version: ") || !detectWindow)) {
|
||||||
lwjgl = true;
|
lwjgl = true;
|
||||||
switch (visibility) {
|
switch (launcherVisibility) {
|
||||||
case HIDE_AND_REOPEN:
|
case HIDE_AND_REOPEN:
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Controllers.getStage().hide();
|
Controllers.getStage().hide();
|
||||||
@@ -518,8 +533,14 @@ public final class LauncherHelper {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
checkExit(visibility);
|
checkExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Queue<ManagedProcess> PROCESSES = new ConcurrentLinkedQueue<>();
|
||||||
|
public static void stopManagedProcesses() {
|
||||||
|
while (!PROCESSES.isEmpty())
|
||||||
|
Optional.ofNullable(PROCESSES.poll()).ifPresent(ManagedProcess::stop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.versions;
|
package org.jackhuang.hmcl.ui.versions;
|
||||||
|
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
|
||||||
|
|
||||||
public class GameListItem extends Control {
|
public class GameListItem extends Control {
|
||||||
private final Profile profile;
|
private final Profile profile;
|
||||||
@@ -83,7 +82,7 @@ public class GameListItem extends Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void launch() {
|
public void launch() {
|
||||||
Versions.launch(profile, version);
|
Versions.testGame(profile, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void modifyGameSettings() {
|
public void modifyGameSettings() {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class GameListItemSkin extends SkinBase<GameListItem> {
|
|||||||
new MenuSeparator(),
|
new MenuSeparator(),
|
||||||
new IconedMenuItem(FXUtils.limitingSize(SVG.folderOpen(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.game"), FXUtils.withJFXPopupClosing(skinnable::browse, popup)),
|
new IconedMenuItem(FXUtils.limitingSize(SVG.folderOpen(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.game"), FXUtils.withJFXPopupClosing(skinnable::browse, popup)),
|
||||||
new MenuSeparator(),
|
new MenuSeparator(),
|
||||||
new IconedMenuItem(FXUtils.limitingSize(SVG.launch(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch"), FXUtils.withJFXPopupClosing(skinnable::launch, popup)),
|
new IconedMenuItem(FXUtils.limitingSize(SVG.launch(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch.test"), FXUtils.withJFXPopupClosing(skinnable::launch, popup)),
|
||||||
new IconedMenuItem(FXUtils.limitingSize(SVG.script(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch_script"), FXUtils.withJFXPopupClosing(skinnable::generateLaunchScript, popup)));
|
new IconedMenuItem(FXUtils.limitingSize(SVG.script(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch_script"), FXUtils.withJFXPopupClosing(skinnable::generateLaunchScript, popup)));
|
||||||
|
|
||||||
HBox right = new HBox();
|
HBox right = new HBox();
|
||||||
|
|||||||
@@ -101,11 +101,8 @@ public class Versions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void generateLaunchScript(Profile profile, String id) {
|
public static void generateLaunchScript(Profile profile, String id) {
|
||||||
GameRepository repository = profile.getRepository();
|
if (checkForLaunching(profile, id)) {
|
||||||
|
GameRepository repository = profile.getRepository();
|
||||||
if (Accounts.getSelectedAccount() == null)
|
|
||||||
Controllers.dialog(i18n("login.empty_username"));
|
|
||||||
else {
|
|
||||||
FileChooser chooser = new FileChooser();
|
FileChooser chooser = new FileChooser();
|
||||||
if (repository.getRunDirectory(id).isDirectory())
|
if (repository.getRunDirectory(id).isDirectory())
|
||||||
chooser.setInitialDirectory(repository.getRunDirectory(id));
|
chooser.setInitialDirectory(repository.getRunDirectory(id));
|
||||||
@@ -115,17 +112,31 @@ public class Versions {
|
|||||||
: new FileChooser.ExtensionFilter(i18n("extension.sh"), "*.sh"));
|
: new FileChooser.ExtensionFilter(i18n("extension.sh"), "*.sh"));
|
||||||
File file = chooser.showSaveDialog(Controllers.getStage());
|
File file = chooser.showSaveDialog(Controllers.getStage());
|
||||||
if (file != null)
|
if (file != null)
|
||||||
LauncherHelper.INSTANCE.launch(profile, Accounts.getSelectedAccount(), id, file);
|
new LauncherHelper(profile, Accounts.getSelectedAccount(), id).makeLaunchScript(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void launch(Profile profile, String id) {
|
public static void launch(Profile profile, String id) {
|
||||||
|
if (checkForLaunching(profile, id))
|
||||||
|
new LauncherHelper(profile, Accounts.getSelectedAccount(), id).launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void testGame(Profile profile, String id) {
|
||||||
|
if (checkForLaunching(profile, id)) {
|
||||||
|
LauncherHelper helper = new LauncherHelper(profile, Accounts.getSelectedAccount(), id);
|
||||||
|
helper.setTestMode();
|
||||||
|
helper.launch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkForLaunching(Profile profile, String id) {
|
||||||
if (Accounts.getSelectedAccount() == null)
|
if (Accounts.getSelectedAccount() == null)
|
||||||
Controllers.getLeftPaneController().checkAccount();
|
Controllers.getLeftPaneController().checkAccount();
|
||||||
else if (id == null)
|
else if (id == null || !profile.getRepository().isLoaded() || !profile.getRepository().hasVersion(id))
|
||||||
Controllers.dialog(i18n("version.empty.launch"));
|
Controllers.dialog(i18n("version.empty.launch"));
|
||||||
else
|
else
|
||||||
LauncherHelper.INSTANCE.launch(profile, Accounts.getSelectedAccount(), id, null);
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void modifyGlobalSettings(Profile profile) {
|
public static void modifyGlobalSettings(Profile profile) {
|
||||||
|
|||||||
@@ -368,6 +368,7 @@ version.game.old=Old
|
|||||||
version.game.release=Release
|
version.game.release=Release
|
||||||
version.game.snapshot=Snapshot
|
version.game.snapshot=Snapshot
|
||||||
version.launch=Play
|
version.launch=Play
|
||||||
|
version.launch.test=Test Game
|
||||||
version.launch_script=Make Launching Script
|
version.launch_script=Make Launching Script
|
||||||
version.launch_script.failed=Unable to make launch script.
|
version.launch_script.failed=Unable to make launch script.
|
||||||
version.launch_script.save=Save the launch script
|
version.launch_script.save=Save the launch script
|
||||||
|
|||||||
@@ -368,6 +368,7 @@ version.game.old=老舊版本
|
|||||||
version.game.release=穩定版本
|
version.game.release=穩定版本
|
||||||
version.game.snapshot=測試版本
|
version.game.snapshot=測試版本
|
||||||
version.launch=啟動遊戲
|
version.launch=啟動遊戲
|
||||||
|
version.launch.test=測試遊戲
|
||||||
version.launch_script=生成啟動腳本
|
version.launch_script=生成啟動腳本
|
||||||
version.launch_script.failed=生成啟動腳本失敗
|
version.launch_script.failed=生成啟動腳本失敗
|
||||||
version.launch_script.save=儲存啟動腳本
|
version.launch_script.save=儲存啟動腳本
|
||||||
|
|||||||
@@ -368,6 +368,7 @@ version.game.old=远古版
|
|||||||
version.game.release=稳定版
|
version.game.release=稳定版
|
||||||
version.game.snapshot=测试版
|
version.game.snapshot=测试版
|
||||||
version.launch=启动游戏
|
version.launch=启动游戏
|
||||||
|
version.launch.test=测试游戏
|
||||||
version.launch_script=生成启动脚本
|
version.launch_script=生成启动脚本
|
||||||
version.launch_script.failed=生成启动脚本失败
|
version.launch_script.failed=生成启动脚本失败
|
||||||
version.launch_script.save=保存启动脚本
|
version.launch_script.save=保存启动脚本
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public final class SelectedItemProperties {
|
|||||||
return new ReadWriteComposedProperty<>(bean, "extra.selectedItem",
|
return new ReadWriteComposedProperty<>(bean, "extra.selectedItem",
|
||||||
MultiStepBinding.of(modelProperty)
|
MultiStepBinding.of(modelProperty)
|
||||||
.flatMap(SelectionModel::selectedItemProperty),
|
.flatMap(SelectionModel::selectedItemProperty),
|
||||||
modelProperty.getValue()::select);
|
obj -> modelProperty.getValue().select(obj));
|
||||||
}
|
}
|
||||||
// ====
|
// ====
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user