feat(multiplayer): wip: hiper

This commit is contained in:
huanghongxun 2022-09-11 13:49:49 +08:00
parent 03541a6f85
commit 99be810b5e
5 changed files with 97 additions and 128 deletions

View File

@ -29,9 +29,9 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class LocalServerBroadcaster implements Runnable { public class LocalServerBroadcaster implements Runnable {
private final int port; private final int port;
private final MultiplayerManager.CatoSession session; private final MultiplayerManager.HiperSession session;
public LocalServerBroadcaster(int port, MultiplayerManager.CatoSession session) { public LocalServerBroadcaster(int port, MultiplayerManager.HiperSession session) {
this.port = port; this.port = port;
this.session = session; this.session = session;
} }

View File

@ -91,7 +91,7 @@ public class MultiplayerClient extends Thread {
LOG.info("Connected to 127.0.0.1:" + port); LOG.info("Connected to 127.0.0.1:" + port);
endpoint.write(new HandshakeRequest()); endpoint.write(new HandshakeRequest());
endpoint.write(new JoinRequest(MultiplayerManager.CATO_VERSION, id)); endpoint.write(new JoinRequest(MultiplayerManager.HIPER_VERSION, id));
LOG.fine("Sent join request with id=" + id); LOG.fine("Sent join request with id=" + id);

View File

@ -31,7 +31,6 @@ import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.io.ChecksumMismatchException; import org.jackhuang.hmcl.util.io.ChecksumMismatchException;
import org.jackhuang.hmcl.util.io.HttpRequest; import org.jackhuang.hmcl.util.io.HttpRequest;
import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.CommandBuilder; import org.jackhuang.hmcl.util.platform.CommandBuilder;
import org.jackhuang.hmcl.util.platform.ManagedProcess; import org.jackhuang.hmcl.util.platform.ManagedProcess;
import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.platform.OperatingSystem;
@ -59,11 +58,12 @@ import static org.jackhuang.hmcl.util.Logging.LOG;
* Cato Management. * Cato Management.
*/ */
public final class MultiplayerManager { public final class MultiplayerManager {
static final String CATO_VERSION = "1.2.2"; static final String HIPER_VERSION = "1.2.2";
private static final String CATO_DOWNLOAD_URL = "https://gitcode.net/to/cato/-/raw/master/client/"; private static final String HIPER_DOWNLOAD_URL = "https://gitcode.net/to/hiper/-/raw/master/";
private static final String CATO_HASH_URL = CATO_DOWNLOAD_URL + "cato-all-files.sha1"; private static final String HIPER_PACKAGES_URL = HIPER_DOWNLOAD_URL + "packages.sha1";
private static final String CATO_PATH = getCatoPath(); private static final Path HIPER_CONFIG_PATH = Metadata.HMCL_DIRECTORY.resolve("hiper.yml");
public static final int CATO_AGREEMENT_VERSION = 2; private static final String HIPER_PATH = getHiperPath();
public static final int HIPER_AGREEMENT_VERSION = 2;
private static final String REMOTE_ADDRESS = "127.0.0.1"; private static final String REMOTE_ADDRESS = "127.0.0.1";
private static final String LOCAL_ADDRESS = "0.0.0.0"; private static final String LOCAL_ADDRESS = "0.0.0.0";
@ -72,18 +72,18 @@ public final class MultiplayerManager {
private MultiplayerManager() { private MultiplayerManager() {
} }
private static CompletableFuture<Map<String, String>> getCatoHash() { private static CompletableFuture<Map<String, String>> getPackagesHash() {
FXUtils.checkFxUserThread(); FXUtils.checkFxUserThread();
if (HASH == null) { if (HASH == null) {
HASH = CompletableFuture.supplyAsync(wrap(() -> { HASH = CompletableFuture.supplyAsync(wrap(() -> {
String hashList = HttpRequest.GET(CATO_HASH_URL).getString(); String hashList = HttpRequest.GET(HIPER_PACKAGES_URL).getString();
Map<String, String> hashes = new HashMap<>(); Map<String, String> hashes = new HashMap<>();
for (String line : hashList.split("\n")) { for (String line : hashList.split("\n")) {
String[] items = line.trim().split(" "); String[] items = line.trim().split(" {2}");
if (items.length == 2 && items[0].length() == 40) { if (items.length == 2 && items[0].length() == 40) {
hashes.put(items[1], items[0]); hashes.put(items[1], items[0]);
} else { } else {
LOG.warning("Failed to parse cato hash file, hash line " + line); LOG.warning("Failed to parse Hiper packages.sha1 file, line: " + line);
} }
} }
return hashes; return hashes;
@ -92,38 +92,34 @@ public final class MultiplayerManager {
return HASH; return HASH;
} }
public static Task<Void> downloadCato() { public static Task<Void> downloadHiper() {
return Task.fromCompletableFuture(getCatoHash()).thenComposeAsync(catoHashes -> return Task.fromCompletableFuture(getPackagesHash()).thenComposeAsync(packagesHash ->
new FileDownloadTask( new FileDownloadTask(
NetworkUtils.toURL(CATO_DOWNLOAD_URL + getCatoFileName()), NetworkUtils.toURL(HIPER_DOWNLOAD_URL + getHiperFileName()),
getCatoExecutable().toFile(), getHiperExecutable().toFile(),
catoHashes.get(getCatoFileName()) == null ? null : new FileDownloadTask.IntegrityCheck("SHA-1", catoHashes.get(getCatoFileName())) packagesHash.get(getHiperFileName()) == null ? null : new FileDownloadTask.IntegrityCheck("SHA-1", packagesHash.get(getHiperFileName()))
).thenRunAsync(() -> { ).thenRunAsync(() -> {
if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX || OperatingSystem.CURRENT_OS == OperatingSystem.OSX) { if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX || OperatingSystem.CURRENT_OS == OperatingSystem.OSX) {
Set<PosixFilePermission> perm = Files.getPosixFilePermissions(getCatoExecutable()); Set<PosixFilePermission> perm = Files.getPosixFilePermissions(getHiperExecutable());
perm.add(PosixFilePermission.OWNER_EXECUTE); perm.add(PosixFilePermission.OWNER_EXECUTE);
Files.setPosixFilePermissions(getCatoExecutable(), perm); Files.setPosixFilePermissions(getHiperExecutable(), perm);
} }
})); }));
} }
public static Path getCatoExecutable() { public static Path getHiperExecutable() {
return Metadata.HMCL_DIRECTORY.resolve("libraries").resolve(CATO_PATH); return Metadata.HMCL_DIRECTORY.resolve("libraries").resolve(HIPER_PATH);
} }
private static CompletableFuture<CatoSession> startCato(String token, State state) { private static CompletableFuture<HiperSession> startHiper(String token, State state) {
return getCatoHash().thenApplyAsync(wrap(catoHashes -> { return getPackagesHash().thenApplyAsync(wrap(packagesHash -> {
Path exe = getCatoExecutable(); Path exe = getHiperExecutable();
if (!Files.isRegularFile(exe)) { if (!Files.isRegularFile(exe)) {
throw new CatoNotExistsException(exe); throw new HiperNotExistsException(exe);
}
if (!isPortAvailable(3478)) {
throw new CatoAlreadyStartedException();
} }
try { try {
String hash = catoHashes.get(getCatoFileName()); String hash = packagesHash.get(getHiperFileName());
if (hash != null) { if (hash != null) {
ChecksumMismatchException.verifyChecksum(exe, "SHA-1", hash); ChecksumMismatchException.verifyChecksum(exe, "SHA-1", hash);
} }
@ -139,28 +135,28 @@ public final class MultiplayerManager {
.command(commands) .command(commands)
.start(); .start();
return new CatoSession(state, process, Arrays.asList(commands)); return new HiperSession(state, process, Arrays.asList(commands));
})); }));
} }
public static CompletableFuture<CatoSession> joinSession(String token, String peer, Mode mode, int remotePort, int localPort, JoinSessionHandler handler) throws IncompatibleCatoVersionException { public static CompletableFuture<HiperSession> joinSession(String token, String peer, Mode mode, int remotePort, int localPort, JoinSessionHandler handler) throws IncompatibleHiperVersionException {
LOG.info(String.format("Joining session (token=%s,peer=%s,mode=%s,remotePort=%d,localPort=%d)", token, peer, mode, remotePort, localPort)); LOG.info(String.format("Joining session (token=%s,peer=%s,mode=%s,remotePort=%d,localPort=%d)", token, peer, mode, remotePort, localPort));
return startCato(token, State.SLAVE).thenComposeAsync(wrap(session -> { return startHiper(token, State.SLAVE).thenComposeAsync(wrap(session -> {
CompletableFuture<CatoSession> future = new CompletableFuture<>(); CompletableFuture<HiperSession> future = new CompletableFuture<>();
session.forwardPort(peer, LOCAL_ADDRESS, localPort, REMOTE_ADDRESS, remotePort, mode); session.forwardPort(peer, LOCAL_ADDRESS, localPort, REMOTE_ADDRESS, remotePort, mode);
Consumer<CatoExitEvent> onExit = event -> { Consumer<HiperExitEvent> onExit = event -> {
boolean ready = session.isReady(); boolean ready = session.isReady();
switch (event.getExitCode()) { switch (event.getExitCode()) {
case 1: case 1:
if (!ready) { if (!ready) {
future.completeExceptionally(new CatoExitTimeoutException()); future.completeExceptionally(new HiperExitTimeoutException());
} }
break; break;
} }
future.completeExceptionally(new CatoExitException(event.getExitCode(), ready)); future.completeExceptionally(new HiperExitException(event.getExitCode(), ready));
}; };
session.onExit.register(onExit); session.onExit.register(onExit);
@ -225,11 +221,11 @@ public final class MultiplayerManager {
})); }));
} }
public static CompletableFuture<CatoSession> createSession(String token, String sessionName, int gamePort, boolean allowAllJoinRequests) { public static CompletableFuture<HiperSession> createSession(String token, String sessionName, int gamePort, boolean allowAllJoinRequests) {
LOG.info(String.format("Creating session (token=%s,sessionName=%s,gamePort=%d)", token, sessionName, gamePort)); LOG.info(String.format("Creating session (token=%s,sessionName=%s,gamePort=%d)", token, sessionName, gamePort));
return startCato(token, State.MASTER).thenComposeAsync(wrap(session -> { return startHiper(token, State.MASTER).thenComposeAsync(wrap(session -> {
CompletableFuture<CatoSession> future = new CompletableFuture<>(); CompletableFuture<HiperSession> future = new CompletableFuture<>();
MultiplayerServer server = new MultiplayerServer(sessionName, gamePort, allowAllJoinRequests); MultiplayerServer server = new MultiplayerServer(sessionName, gamePort, allowAllJoinRequests);
server.startServer(); server.startServer();
@ -239,16 +235,16 @@ public final class MultiplayerManager {
session.allowForwardingAddress(REMOTE_ADDRESS, gamePort); session.allowForwardingAddress(REMOTE_ADDRESS, gamePort);
session.showAllowedAddress(); session.showAllowedAddress();
Consumer<CatoExitEvent> onExit = event -> { Consumer<HiperExitEvent> onExit = event -> {
boolean ready = session.isReady(); boolean ready = session.isReady();
switch (event.getExitCode()) { switch (event.getExitCode()) {
case 1: case 1:
if (!ready) { if (!ready) {
future.completeExceptionally(new CatoExitTimeoutException()); future.completeExceptionally(new HiperExitTimeoutException());
} }
break; break;
} }
future.completeExceptionally(new CatoExitException(event.getExitCode(), ready)); future.completeExceptionally(new HiperExitException(event.getExitCode(), ready));
}; };
session.onExit.register(onExit); session.onExit.register(onExit);
@ -294,49 +290,22 @@ public final class MultiplayerManager {
} }
} }
private static String getCatoFileName() { private static String getHiperFileName() {
switch (OperatingSystem.CURRENT_OS) { if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
case WINDOWS: return "hiper.exe";
if (Architecture.SYSTEM_ARCH == Architecture.X86_64) { } else {
return "cato-client-windows-amd64.exe"; return "hiper";
} else if (Architecture.SYSTEM_ARCH == Architecture.ARM64) {
return "cato-client-windows-arm64.exe";
} else if (Architecture.SYSTEM_ARCH == Architecture.X86) {
return "cato-client-windows-i386.exe";
} else {
return "";
}
case OSX:
if (Architecture.SYSTEM_ARCH == Architecture.X86_64) {
return "cato-client-darwin-amd64";
} else if (Architecture.SYSTEM_ARCH == Architecture.ARM64) {
return "cato-client-darwin-arm64";
} else {
return "";
}
case LINUX:
if (Architecture.SYSTEM_ARCH == Architecture.X86_64) {
return "cato-client-linux-amd64";
} else if (Architecture.SYSTEM_ARCH == Architecture.ARM32) {
return "cato-client-linux-arm7";
} else if (Architecture.SYSTEM_ARCH == Architecture.ARM64) {
return "cato-client-linux-arm64";
} else {
return "";
}
default:
return "";
} }
} }
public static String getCatoPath() { public static String getHiperPath() {
String name = getCatoFileName(); String name = getHiperFileName();
if (StringUtils.isBlank(name)) return ""; if (StringUtils.isBlank(name)) return "";
return "cato/cato/" + MultiplayerManager.CATO_VERSION + "/" + name; return "hiper/hiper/" + MultiplayerManager.HIPER_VERSION + "/" + name;
} }
public static class CatoSession extends ManagedProcess { public static class HiperSession extends ManagedProcess {
private final EventManager<CatoExitEvent> onExit = new EventManager<>(); private final EventManager<HiperExitEvent> onExit = new EventManager<>();
private final EventManager<CatoIdEvent> onIdGenerated = new EventManager<>(); private final EventManager<CatoIdEvent> onIdGenerated = new EventManager<>();
private final EventManager<Event> onPeerConnected = new EventManager<>(); private final EventManager<Event> onPeerConnected = new EventManager<>();
@ -348,15 +317,15 @@ public final class MultiplayerManager {
private MultiplayerServer server; private MultiplayerServer server;
private final BufferedWriter writer; private final BufferedWriter writer;
CatoSession(State type, Process process, List<String> commands) { HiperSession(State type, Process process, List<String> commands) {
super(process, commands); super(process, commands);
Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
LOG.info("Started cato with command: " + new CommandBuilder().addAll(commands)); LOG.info("Started hiper with command: " + new CommandBuilder().addAll(commands));
this.type = type; this.type = type;
addRelatedThread(Lang.thread(this::waitFor, "CatoExitWaiter", true)); addRelatedThread(Lang.thread(this::waitFor, "HiperExitWaiter", true));
pumpInputStream(this::checkCatoLog); pumpInputStream(this::checkCatoLog);
pumpErrorStream(this::checkCatoLog); pumpErrorStream(this::checkCatoLog);
@ -367,7 +336,7 @@ public final class MultiplayerManager {
return client; return client;
} }
public synchronized CatoSession setClient(MultiplayerClient client) { public synchronized HiperSession setClient(MultiplayerClient client) {
this.client = client; this.client = client;
return this; return this;
} }
@ -376,13 +345,13 @@ public final class MultiplayerManager {
return server; return server;
} }
public CatoSession setServer(MultiplayerServer server) { public HiperSession setServer(MultiplayerServer server) {
this.server = server; this.server = server;
return this; return this;
} }
private void checkCatoLog(String log) { private void checkCatoLog(String log) {
LOG.info("Cato: " + log); LOG.info("[Hiper] " + log);
if (id == null) { if (id == null) {
Matcher matcher = TEMP_TOKEN_PATTERN.matcher(log); Matcher matcher = TEMP_TOKEN_PATTERN.matcher(log);
if (matcher.find()) { if (matcher.find()) {
@ -403,16 +372,16 @@ public final class MultiplayerManager {
private void waitFor() { private void waitFor() {
try { try {
int exitCode = getProcess().waitFor(); int exitCode = getProcess().waitFor();
LOG.info("cato exited with exitcode " + exitCode); LOG.info("Hiper exited with exitcode " + exitCode);
onExit.fireEvent(new CatoExitEvent(this, exitCode)); onExit.fireEvent(new HiperExitEvent(this, exitCode));
} catch (InterruptedException e) { } catch (InterruptedException e) {
onExit.fireEvent(new CatoExitEvent(this, CatoExitEvent.EXIT_CODE_INTERRUPTED)); onExit.fireEvent(new HiperExitEvent(this, HiperExitEvent.EXIT_CODE_INTERRUPTED));
} finally { } finally {
try { try {
if (writer != null) if (writer != null)
writer.close(); writer.close();
} catch (IOException e) { } catch (IOException e) {
LOG.log(Level.WARNING, "Failed to close cato stdin writer", e); LOG.log(Level.WARNING, "Failed to close Hiper stdin writer", e);
} }
} }
destroyRelatedThreads(); destroyRelatedThreads();
@ -447,7 +416,7 @@ public final class MultiplayerManager {
} }
public synchronized void invokeCommand(String command) throws IOException { public synchronized void invokeCommand(String command) throws IOException {
LOG.info("Invoking cato: " + command); LOG.info("Invoking hiper: " + command);
writer.write(command); writer.write(command);
writer.newLine(); writer.newLine();
writer.flush(); writer.flush();
@ -465,7 +434,7 @@ public final class MultiplayerManager {
invokeCommand("ufw net whitelist"); invokeCommand("ufw net whitelist");
} }
public EventManager<CatoExitEvent> onExit() { public EventManager<HiperExitEvent> onExit() {
return onExit; return onExit;
} }
@ -482,10 +451,10 @@ public final class MultiplayerManager {
private static final Pattern LOG_PATTERN = Pattern.compile("(\\[\\d+])\\s+(\\w+)\\s+(\\w+-{0,1}\\w+):\\s(.*)"); private static final Pattern LOG_PATTERN = Pattern.compile("(\\[\\d+])\\s+(\\w+)\\s+(\\w+-{0,1}\\w+):\\s(.*)");
} }
public static class CatoExitEvent extends Event { public static class HiperExitEvent extends Event {
private final int exitCode; private final int exitCode;
public CatoExitEvent(Object source, int exitCode) { public HiperExitEvent(Object source, int exitCode) {
super(source); super(source);
this.exitCode = exitCode; this.exitCode = exitCode;
} }
@ -541,11 +510,11 @@ public final class MultiplayerManager {
void onWaitingForJoinResponse(); void onWaitingForJoinResponse();
} }
public static class IncompatibleCatoVersionException extends Exception { public static class IncompatibleHiperVersionException extends Exception {
private final String expected; private final String expected;
private final String actual; private final String actual;
public IncompatibleCatoVersionException(String expected, String actual) { public IncompatibleHiperVersionException(String expected, String actual) {
this.expected = expected; this.expected = expected;
this.actual = actual; this.actual = actual;
} }
@ -568,11 +537,11 @@ public final class MultiplayerManager {
} }
} }
public static class CatoExitException extends RuntimeException { public static class HiperExitException extends RuntimeException {
private final int exitCode; private final int exitCode;
private final boolean ready; private final boolean ready;
public CatoExitException(int exitCode, boolean ready) { public HiperExitException(int exitCode, boolean ready) {
this.exitCode = exitCode; this.exitCode = exitCode;
this.ready = ready; this.ready = ready;
} }
@ -586,13 +555,13 @@ public final class MultiplayerManager {
} }
} }
public static class CatoExitTimeoutException extends RuntimeException { public static class HiperExitTimeoutException extends RuntimeException {
} }
public static class CatoSessionExpiredException extends RuntimeException { public static class HiperSessionExpiredException extends RuntimeException {
} }
public static class CatoAlreadyStartedException extends RuntimeException { public static class HiperAlreadyStartedException extends RuntimeException {
} }
public static class JoinRequestTimeoutException extends RuntimeException { public static class JoinRequestTimeoutException extends RuntimeException {
@ -616,10 +585,10 @@ public final class MultiplayerManager {
} }
} }
public static class CatoNotExistsException extends RuntimeException { public static class HiperNotExistsException extends RuntimeException {
private final Path file; private final Path file;
public CatoNotExistsException(Path file) { public HiperNotExistsException(Path file) {
this.file = file; this.file = file;
} }

View File

@ -64,10 +64,10 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
private final ReadOnlyStringWrapper token = new ReadOnlyStringWrapper(); private final ReadOnlyStringWrapper token = new ReadOnlyStringWrapper();
private final ReadOnlyObjectWrapper<@Nullable Result<DiscoveryInfo>> natState = new ReadOnlyObjectWrapper<>(); private final ReadOnlyObjectWrapper<@Nullable Result<DiscoveryInfo>> natState = new ReadOnlyObjectWrapper<>();
private final ReadOnlyIntegerWrapper gamePort = new ReadOnlyIntegerWrapper(-1); private final ReadOnlyIntegerWrapper gamePort = new ReadOnlyIntegerWrapper(-1);
private final ReadOnlyObjectWrapper<MultiplayerManager.CatoSession> session = new ReadOnlyObjectWrapper<>(); private final ReadOnlyObjectWrapper<MultiplayerManager.HiperSession> session = new ReadOnlyObjectWrapper<>();
private final ObservableList<MultiplayerChannel.CatoClient> clients = FXCollections.observableArrayList(); private final ObservableList<MultiplayerChannel.CatoClient> clients = FXCollections.observableArrayList();
private Consumer<MultiplayerManager.CatoExitEvent> onExit; private Consumer<MultiplayerManager.HiperExitEvent> onExit;
private Consumer<MultiplayerManager.CatoIdEvent> onIdGenerated; private Consumer<MultiplayerManager.CatoIdEvent> onIdGenerated;
private Consumer<Event> onPeerConnected; private Consumer<Event> onPeerConnected;
@ -125,11 +125,11 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
return gamePort.getReadOnlyProperty(); return gamePort.getReadOnlyProperty();
} }
public MultiplayerManager.CatoSession getSession() { public MultiplayerManager.HiperSession getSession() {
return session.get(); return session.get();
} }
public ReadOnlyObjectProperty<MultiplayerManager.CatoSession> sessionProperty() { public ReadOnlyObjectProperty<MultiplayerManager.HiperSession> sessionProperty() {
return session.getReadOnlyProperty(); return session.getReadOnlyProperty();
} }
@ -148,7 +148,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
} }
private void checkAgreement(Runnable runnable) { private void checkAgreement(Runnable runnable) {
if (globalConfig().getMultiplayerAgreementVersion() < MultiplayerManager.CATO_AGREEMENT_VERSION) { if (globalConfig().getMultiplayerAgreementVersion() < MultiplayerManager.HIPER_AGREEMENT_VERSION) {
JFXDialogLayout agreementPane = new JFXDialogLayout(); JFXDialogLayout agreementPane = new JFXDialogLayout();
agreementPane.setHeading(new Label(i18n("launcher.agreement"))); agreementPane.setHeading(new Label(i18n("launcher.agreement")));
agreementPane.setBody(new Label(i18n("multiplayer.agreement.prompt"))); agreementPane.setBody(new Label(i18n("multiplayer.agreement.prompt")));
@ -157,7 +157,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
JFXButton yesButton = new JFXButton(i18n("launcher.agreement.accept")); JFXButton yesButton = new JFXButton(i18n("launcher.agreement.accept"));
yesButton.getStyleClass().add("dialog-accept"); yesButton.getStyleClass().add("dialog-accept");
yesButton.setOnAction(e -> { yesButton.setOnAction(e -> {
globalConfig().setMultiplayerAgreementVersion(MultiplayerManager.CATO_AGREEMENT_VERSION); globalConfig().setMultiplayerAgreementVersion(MultiplayerManager.HIPER_AGREEMENT_VERSION);
runnable.run(); runnable.run();
agreementPane.fireEvent(new DialogCloseEvent()); agreementPane.fireEvent(new DialogCloseEvent());
}); });
@ -175,15 +175,15 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
} }
private void downloadCatoIfNecessary() { private void downloadCatoIfNecessary() {
if (StringUtils.isBlank(MultiplayerManager.getCatoPath())) { if (StringUtils.isBlank(MultiplayerManager.getHiperPath())) {
Controllers.dialog(i18n("multiplayer.download.unsupported"), i18n("install.failed.downloading"), MessageDialogPane.MessageType.ERROR); Controllers.dialog(i18n("multiplayer.download.unsupported"), i18n("install.failed.downloading"), MessageDialogPane.MessageType.ERROR);
fireEvent(new PageCloseEvent()); fireEvent(new PageCloseEvent());
return; return;
} }
if (!MultiplayerManager.getCatoExecutable().toFile().exists()) { if (!MultiplayerManager.getHiperExecutable().toFile().exists()) {
setDisabled(true); setDisabled(true);
TaskExecutor executor = MultiplayerManager.downloadCato() TaskExecutor executor = MultiplayerManager.downloadHiper()
.whenComplete(Schedulers.javafx(), exception -> { .whenComplete(Schedulers.javafx(), exception -> {
setDisabled(false); setDisabled(false);
if (exception != null) { if (exception != null) {
@ -325,7 +325,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
reject.accept(localizeJoinErrorMessage(throwable, isStaticToken)); reject.accept(localizeJoinErrorMessage(throwable, isStaticToken));
return null; return null;
}); });
} catch (MultiplayerManager.IncompatibleCatoVersionException e) { } catch (MultiplayerManager.IncompatibleHiperVersionException e) {
reject.accept(i18n("multiplayer.session.join.invitation_code.version")); reject.accept(i18n("multiplayer.session.join.invitation_code.version"));
} }
}) })
@ -353,11 +353,11 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
} else if (e instanceof MultiplayerManager.KickedException) { } else if (e instanceof MultiplayerManager.KickedException) {
LOG.info("Kicked by server"); LOG.info("Kicked by server");
return i18n("multiplayer.session.join.kicked", localizeKickMessage(((MultiplayerManager.KickedException) e).getReason())); return i18n("multiplayer.session.join.kicked", localizeKickMessage(((MultiplayerManager.KickedException) e).getReason()));
} else if (e instanceof MultiplayerManager.CatoAlreadyStartedException) { } else if (e instanceof MultiplayerManager.HiperAlreadyStartedException) {
LOG.info("Cato already started"); LOG.info("Cato already started");
return i18n("multiplayer.session.error.already_started"); return i18n("multiplayer.session.error.already_started");
} else if (e instanceof MultiplayerManager.CatoNotExistsException) { } else if (e instanceof MultiplayerManager.HiperNotExistsException) {
LOG.log(Level.WARNING, "Cato not found " + ((MultiplayerManager.CatoNotExistsException) e).getFile(), e); LOG.log(Level.WARNING, "Cato not found " + ((MultiplayerManager.HiperNotExistsException) e).getFile(), e);
return i18n("multiplayer.session.error.file_not_found"); return i18n("multiplayer.session.error.file_not_found");
} else if (e instanceof MultiplayerManager.JoinRequestTimeoutException) { } else if (e instanceof MultiplayerManager.JoinRequestTimeoutException) {
LOG.info("Cato already started"); LOG.info("Cato already started");
@ -365,17 +365,17 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
} else if (e instanceof MultiplayerManager.ConnectionErrorException) { } else if (e instanceof MultiplayerManager.ConnectionErrorException) {
LOG.info("Failed to establish connection with server"); LOG.info("Failed to establish connection with server");
return i18n("multiplayer.session.join.error.connection"); return i18n("multiplayer.session.join.error.connection");
} else if (e instanceof MultiplayerManager.CatoExitTimeoutException) { } else if (e instanceof MultiplayerManager.HiperExitTimeoutException) {
LOG.info("Cato failed to connect to main net"); LOG.info("Cato failed to connect to main net");
if (isStaticToken) { if (isStaticToken) {
return i18n("multiplayer.exit.timeout.static_token"); return i18n("multiplayer.exit.timeout.static_token");
} else { } else {
return i18n("multiplayer.exit.timeout.dynamic_token"); return i18n("multiplayer.exit.timeout.dynamic_token");
} }
} else if (e instanceof MultiplayerManager.CatoExitException) { } else if (e instanceof MultiplayerManager.HiperExitException) {
LOG.info("Cato exited accidentally"); LOG.info("Cato exited accidentally");
int exitCode = ((MultiplayerManager.CatoExitException) e).getExitCode(); int exitCode = ((MultiplayerManager.HiperExitException) e).getExitCode();
if (!((MultiplayerManager.CatoExitException) e).isReady()) { if (!((MultiplayerManager.HiperExitException) e).isReady()) {
return i18n("multiplayer.exit.before_ready", exitCode); return i18n("multiplayer.exit.before_ready", exitCode);
} else { } else {
return i18n("multiplayer.exit.after_ready", exitCode); return i18n("multiplayer.exit.after_ready", exitCode);
@ -442,7 +442,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
stopCatoSession(); stopCatoSession();
} }
private void initCatoSession(MultiplayerManager.CatoSession session) { private void initCatoSession(MultiplayerManager.HiperSession session) {
runInFX(() -> { runInFX(() -> {
onExit = session.onExit().registerWeak(this::onCatoExit); onExit = session.onExit().registerWeak(this::onCatoExit);
onIdGenerated = session.onIdGenerated().registerWeak(this::onCatoIdGenerated); onIdGenerated = session.onIdGenerated().registerWeak(this::onCatoIdGenerated);
@ -467,13 +467,13 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
this.multiplayerState.set(MultiplayerManager.State.DISCONNECTED); this.multiplayerState.set(MultiplayerManager.State.DISCONNECTED);
} }
private void onCatoExit(MultiplayerManager.CatoExitEvent event) { private void onCatoExit(MultiplayerManager.HiperExitEvent event) {
runInFX(() -> { runInFX(() -> {
boolean ready = ((MultiplayerManager.CatoSession) event.getSource()).isReady(); boolean ready = ((MultiplayerManager.HiperSession) event.getSource()).isReady();
switch (event.getExitCode()) { switch (event.getExitCode()) {
case 0: case 0:
break; break;
case MultiplayerManager.CatoExitEvent.EXIT_CODE_SESSION_EXPIRED: case MultiplayerManager.HiperExitEvent.EXIT_CODE_SESSION_EXPIRED:
Controllers.dialog(i18n("multiplayer.session.expired")); Controllers.dialog(i18n("multiplayer.session.expired"));
break; break;
case 1: case 1:
@ -485,7 +485,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
// do nothing // do nothing
break; break;
default: default:
if (!((MultiplayerManager.CatoSession) event.getSource()).isReady()) { if (!((MultiplayerManager.HiperSession) event.getSource()).isReady()) {
Controllers.dialog(i18n("multiplayer.exit.before_ready", event.getExitCode())); Controllers.dialog(i18n("multiplayer.exit.before_ready", event.getExitCode()));
} else { } else {
Controllers.dialog(i18n("multiplayer.exit.after_ready", event.getExitCode())); Controllers.dialog(i18n("multiplayer.exit.after_ready", event.getExitCode()));
@ -505,7 +505,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
private void onCatoIdGenerated(MultiplayerManager.CatoIdEvent event) { private void onCatoIdGenerated(MultiplayerManager.CatoIdEvent event) {
runInFX(() -> { runInFX(() -> {
token.set(event.getId()); token.set(event.getId());
setMultiplayerState(((MultiplayerManager.CatoSession) event.getSource()).getType()); setMultiplayerState(((MultiplayerManager.HiperSession) event.getSource()).getType());
}); });
} }

View File

@ -153,7 +153,7 @@ public class MultiplayerServer extends Thread {
LOG.info("Received join request with clientVersion=" + joinRequest.getClientVersion() + ", id=" + joinRequest.getUsername()); LOG.info("Received join request with clientVersion=" + joinRequest.getClientVersion() + ", id=" + joinRequest.getUsername());
clientName = joinRequest.getUsername(); clientName = joinRequest.getUsername();
if (!Objects.equals(MultiplayerManager.CATO_VERSION, joinRequest.getClientVersion())) { if (!Objects.equals(MultiplayerManager.HIPER_VERSION, joinRequest.getClientVersion())) {
try { try {
endpoint.write(new KickResponse(KickResponse.VERSION_NOT_MATCHED)); endpoint.write(new KickResponse(KickResponse.VERSION_NOT_MATCHED));
LOG.info("Rejected join request from id=" + joinRequest.getUsername()); LOG.info("Rejected join request from id=" + joinRequest.getUsername());