mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-19 08:46:09 -04:00
完善 HiPer 支持 (#1821)
* Display hiper token expiration time * Automatically download missing files when starting HiPer * Disable start HiPer when token is empty
This commit is contained in:
parent
8687bb9487
commit
af107b15c0
@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hmcl.ui.multiplayer;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import org.jackhuang.hmcl.Metadata;
|
||||
@ -26,9 +27,9 @@ import org.jackhuang.hmcl.event.EventManager;
|
||||
import org.jackhuang.hmcl.setting.ConfigHolder;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.util.*;
|
||||
import org.jackhuang.hmcl.util.gson.DateTypeAdapter;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
@ -44,6 +45,9 @@ import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -54,6 +58,7 @@ import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
|
||||
import static org.jackhuang.hmcl.util.Lang.*;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
import static org.jackhuang.hmcl.util.io.ChecksumMismatchException.verifyChecksum;
|
||||
|
||||
/**
|
||||
@ -105,9 +110,14 @@ public final class MultiplayerManager {
|
||||
static final boolean IS_ADMINISTRATOR;
|
||||
|
||||
static final BooleanBinding tokenInvalid = Bindings.createBooleanBinding(
|
||||
() -> !StringUtils.isAlphabeticOrNumber(globalConfig().multiplayerTokenProperty().getValue()),
|
||||
() -> {
|
||||
String token = globalConfig().multiplayerTokenProperty().getValue();
|
||||
return token == null || token.isEmpty() || !StringUtils.isAlphabeticOrNumber(token);
|
||||
},
|
||||
globalConfig().multiplayerTokenProperty());
|
||||
|
||||
private static final DateFormat HIPER_VALID_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
static {
|
||||
boolean isAdministrator = false;
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
@ -220,11 +230,8 @@ public final class MultiplayerManager {
|
||||
}
|
||||
|
||||
public static CompletableFuture<HiperSession> startHiper(String token) {
|
||||
return getPackagesHash().thenApplyAsync(wrap(packagesHash -> {
|
||||
if (!Files.isRegularFile(HIPER_PATH)) {
|
||||
throw new HiperNotExistsException(HIPER_PATH);
|
||||
}
|
||||
|
||||
return getPackagesHash().thenComposeAsync(packagesHash -> {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
try {
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
verifyChecksum(getHiperLocalDirectory().resolve("hiper.exe"), "SHA-1", packagesHash.get(String.format("%s/hiper.exe", HIPER_TARGET_NAME)));
|
||||
@ -235,12 +242,20 @@ public final class MultiplayerManager {
|
||||
} else {
|
||||
verifyChecksum(getHiperLocalDirectory().resolve("hiper"), "SHA-1", packagesHash.get(String.format("%s/hiper", HIPER_TARGET_NAME)));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// force redownload
|
||||
Files.deleteIfExists(HIPER_PATH);
|
||||
throw e;
|
||||
}
|
||||
|
||||
future.complete(null);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to verify HiPer files", e);
|
||||
Platform.runLater(() -> Controllers.taskDialog(MultiplayerManager.downloadHiper()
|
||||
.whenComplete(exception -> {
|
||||
if (exception == null)
|
||||
future.complete(null);
|
||||
else
|
||||
future.completeExceptionally(exception);
|
||||
}), i18n("multiplayer.download"), TaskCancellationAction.NORMAL));
|
||||
}
|
||||
return future;
|
||||
}).thenApplyAsync(wrap(ignored -> {
|
||||
Path configPath = getConfigPath(token);
|
||||
Files.createDirectories(configPath.getParent());
|
||||
|
||||
@ -361,9 +376,11 @@ public final class MultiplayerManager {
|
||||
Optional<String> validUntil = tryCast(logJson.get("valid"), String.class);
|
||||
if (validUntil.isPresent()) {
|
||||
try {
|
||||
Date date = DateTypeAdapter.deserializeToDate(validUntil.get());
|
||||
onValidUntil.fireEvent(new HiperShowValidUntilEvent(this, date));
|
||||
} catch (JsonParseException e) {
|
||||
synchronized (HIPER_VALID_TIME_FORMAT) {
|
||||
Date date = HIPER_VALID_TIME_FORMAT.parse(validUntil.get());
|
||||
onValidUntil.fireEvent(new HiperShowValidUntilEvent(this, date));
|
||||
}
|
||||
} catch (JsonParseException | ParseException e) {
|
||||
LOG.log(Level.WARNING, "Failed to parse certification expire time string: " + validUntil.get());
|
||||
}
|
||||
}
|
||||
@ -527,18 +544,6 @@ public final class MultiplayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static class HiperNotExistsException extends RuntimeException {
|
||||
private final Path file;
|
||||
|
||||
public HiperNotExistsException(Path file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public Path getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HiperInvalidTokenException extends RuntimeException {
|
||||
}
|
||||
|
||||
|
@ -217,11 +217,8 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
|
||||
} else if (e instanceof MultiplayerManager.HiperInvalidConfigurationException) {
|
||||
LOG.warning("HiPer invalid configuration");
|
||||
return i18n("multiplayer.token.malformed");
|
||||
} else if (e instanceof MultiplayerManager.HiperNotExistsException) {
|
||||
LOG.log(Level.WARNING, "Hiper not found " + ((MultiplayerManager.HiperNotExistsException) e).getFile(), e);
|
||||
return i18n("multiplayer.error.file_not_found");
|
||||
} else if (e instanceof ChecksumMismatchException) {
|
||||
LOG.log(Level.WARNING, "HiPer files are not verified", e);
|
||||
LOG.log(Level.WARNING, "Failed to verify HiPer files", e);
|
||||
return i18n("multiplayer.error.file_not_found");
|
||||
} else if (e instanceof MultiplayerManager.HiperExitException) {
|
||||
int exitCode = ((MultiplayerManager.HiperExitException) e).getExitCode();
|
||||
@ -284,6 +281,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
|
||||
|
||||
private void clearSession() {
|
||||
this.session.set(null);
|
||||
this.expireTime.set(null);
|
||||
this.onExit = null;
|
||||
this.onIPAllocated = null;
|
||||
this.onValidUntil = null;
|
||||
|
@ -184,7 +184,7 @@ public class MultiplayerPageSkin extends DecoratorAnimatedPage.DecoratorAnimated
|
||||
expirationLabel.textProperty().bind(Bindings.createStringBinding(() ->
|
||||
control.getExpireTime() == null ? "" : Locales.SIMPLE_DATE_FORMAT.get().format(control.getExpireTime()),
|
||||
control.expireTimeProperty()));
|
||||
expirationPane.setCenter(expirationLabel);
|
||||
expirationPane.setRight(expirationLabel);
|
||||
|
||||
GridPane masterPane = new GridPane();
|
||||
masterPane.setVgap(8);
|
||||
|
@ -907,7 +907,7 @@ multiplayer.slave.server_address=Creator server address
|
||||
multiplayer.slave.server_address.start=Join
|
||||
multiplayer.slave.server_address.stop=Exit
|
||||
multiplayer.slave.video_tutorial=Video Tutorial
|
||||
multiplayer.session.expiration=Expire Time
|
||||
multiplayer.session.expiration=Token Expiration Time
|
||||
|
||||
datapack=Datapacks
|
||||
datapack.add=Install datapack
|
||||
|
@ -752,7 +752,7 @@ multiplayer.slave.server_address=創建方伺服器地址
|
||||
multiplayer.slave.server_address.start=加入
|
||||
multiplayer.slave.server_address.stop=退出
|
||||
multiplayer.slave.video_tutorial=教學影片
|
||||
multiplayer.session.expiration=本次使用截止時間
|
||||
multiplayer.session.expiration=索引碼到期時間
|
||||
|
||||
datapack=資料包
|
||||
datapack.add=加入資料包
|
||||
|
@ -752,7 +752,7 @@ multiplayer.slave.server_address=创建方服务器地址
|
||||
multiplayer.slave.server_address.start=加入
|
||||
multiplayer.slave.server_address.stop=退出
|
||||
multiplayer.slave.video_tutorial=参与者视频教程
|
||||
multiplayer.session.expiration=本次使用截止时间
|
||||
multiplayer.session.expiration=索引码到期时间
|
||||
|
||||
datapack=数据包
|
||||
datapack.add=添加数据包
|
||||
|
Loading…
x
Reference in New Issue
Block a user