fix(multiplayer): ConcurrentModificationException. Closes #1278.

This commit is contained in:
huanghongxun
2022-01-02 01:19:14 +08:00
parent 10fea79a35
commit ebe880bd39
3 changed files with 32 additions and 23 deletions

View File

@@ -54,11 +54,11 @@ public class MultiplayerClient extends Thread {
setDaemon(true); setDaemon(true);
} }
public void setGamePort(int gamePort) { public synchronized void setGamePort(int gamePort) {
this.gamePort = gamePort; this.gamePort = gamePort;
} }
public int getGamePort() { public synchronized int getGamePort() {
return gamePort; return gamePort;
} }

View File

@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.multiplayer;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import javafx.application.Platform;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.event.Event; import org.jackhuang.hmcl.event.Event;
import org.jackhuang.hmcl.event.EventManager; import org.jackhuang.hmcl.event.EventManager;
@@ -175,7 +176,7 @@ public final class MultiplayerManager {
session.setClient(client); session.setClient(client);
TimerTask task = Lang.setTimeout(() -> { TimerTask task = Lang.setTimeout(() -> {
future.completeExceptionally(new JoinRequestTimeoutException()); Platform.runLater(() -> future.completeExceptionally(new JoinRequestTimeoutException()));
session.stop(); session.stop();
}, 30 * 1000); }, 30 * 1000);
@@ -186,25 +187,31 @@ public final class MultiplayerManager {
session.addRelatedThread(Lang.thread(new LocalServerBroadcaster(port, session), "LocalServerBroadcaster", true)); session.addRelatedThread(Lang.thread(new LocalServerBroadcaster(port, session), "LocalServerBroadcaster", true));
session.setName(connectedEvent.getSessionName()); session.setName(connectedEvent.getSessionName());
client.setGamePort(port); client.setGamePort(port);
Platform.runLater(() -> {
session.onExit.unregister(onExit); session.onExit.unregister(onExit);
future.complete(session); future.complete(session);
});
} catch (IOException e) { } catch (IOException e) {
future.completeExceptionally(e);
session.stop(); session.stop();
Platform.runLater(() -> future.completeExceptionally(e));
} }
task.cancel(); task.cancel();
}); });
client.onKicked().register(kickedEvent -> { client.onKicked().register(kickedEvent -> {
future.completeExceptionally(new KickedException(kickedEvent.getReason()));
session.stop(); session.stop();
task.cancel(); task.cancel();
Platform.runLater(() -> {
future.completeExceptionally(new KickedException(kickedEvent.getReason()));
});
}); });
client.onDisconnected().register(disconnectedEvent -> { client.onDisconnected().register(disconnectedEvent -> {
Platform.runLater(() -> {
if (!client.isConnected()) { if (!client.isConnected()) {
// We fail to establish connection with server // We fail to establish connection with server
future.completeExceptionally(new ConnectionErrorException()); future.completeExceptionally(new ConnectionErrorException());
} }
}); });
});
client.onHandshake().register(handshakeEvent -> { client.onHandshake().register(handshakeEvent -> {
if (handler != null) { if (handler != null) {
handler.onWaitingForJoinResponse(); handler.onWaitingForJoinResponse();
@@ -253,9 +260,11 @@ public final class MultiplayerManager {
}, 15 * 1000); }, 15 * 1000);
session.onPeerConnected.register(event -> { session.onPeerConnected.register(event -> {
peerConnectionTimeoutTask.cancel();
Platform.runLater(() -> {
session.onExit.unregister(onExit); session.onExit.unregister(onExit);
future.complete(session); future.complete(session);
peerConnectionTimeoutTask.cancel(); });
}); });
return future; return future;
@@ -353,11 +362,11 @@ public final class MultiplayerManager {
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8)); writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), StandardCharsets.UTF_8));
} }
public MultiplayerClient getClient() { public synchronized MultiplayerClient getClient() {
return client; return client;
} }
public CatoSession setClient(MultiplayerClient client) { public synchronized CatoSession setClient(MultiplayerClient client) {
this.client = client; this.client = client;
return this; return this;
} }
@@ -412,11 +421,11 @@ public final class MultiplayerManager {
return id != null; return id != null;
} }
public String getName() { public synchronized String getName() {
return name; return name;
} }
public void setName(String name) { public synchronized void setName(String name) {
this.name = name; this.name = name;
} }

View File

@@ -111,11 +111,11 @@ public class ManagedProcess {
/** /**
* Add related thread. * Add related thread.
* * <p>
* If a thread is monitoring this raw process, * If a thread is monitoring this raw process,
* you are required to add the instance by this method. * you are required to add the instance by this method.
*/ */
public void addRelatedThread(Thread thread) { public synchronized void addRelatedThread(Thread thread) {
relatedThreads.add(thread); relatedThreads.add(thread);
} }
@@ -146,7 +146,7 @@ public class ManagedProcess {
destroyRelatedThreads(); destroyRelatedThreads();
} }
public void destroyRelatedThreads() { public synchronized void destroyRelatedThreads() {
relatedThreads.forEach(Thread::interrupt); relatedThreads.forEach(Thread::interrupt);
} }