From d3dd0d1bb9e6e90e7120f8d77507e62291ad3ee0 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Fri, 5 Apr 2024 15:22:40 -0700 Subject: [PATCH 1/4] Minimize Handshake interface Since the clientserver code does not understand what a `Player` is, we can't have `Handshake.getPlayer()`. Since this method is only used called on `ServerHandshake`, the method has been moved there and removed from `Handshake` and `ClientHandshake`. Additionally, the `Handshake` interface does not need to inherit from `MessageHandler`. Implementations can be `MessageHandler` if they need to be (and they current do), but nothing about the handshake process inherently requires this to be true. --- .../net/rptools/maptool/client/MapToolConnection.java | 3 +-- .../net/rptools/maptool/server/ClientHandshake.java | 6 ------ .../java/net/rptools/maptool/server/Handshake.java | 11 +---------- .../maptool/server/MapToolServerConnection.java | 11 +++++++++-- .../net/rptools/maptool/server/ServerHandshake.java | 6 +++++- 5 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/MapToolConnection.java b/src/main/java/net/rptools/maptool/client/MapToolConnection.java index 320f5a0369..bf3200a788 100644 --- a/src/main/java/net/rptools/maptool/client/MapToolConnection.java +++ b/src/main/java/net/rptools/maptool/client/MapToolConnection.java @@ -21,7 +21,6 @@ import net.rptools.maptool.client.ui.ActivityMonitorPanel; import net.rptools.maptool.model.player.LocalPlayer; import net.rptools.maptool.server.ClientHandshake; -import net.rptools.maptool.server.Handshake; import net.rptools.maptool.server.ServerConfig; import net.rptools.maptool.server.proto.Message; import org.apache.logging.log4j.LogManager; @@ -37,7 +36,7 @@ public class MapToolConnection { private final LocalPlayer player; private Connection connection; - private Handshake handshake; + private ClientHandshake handshake; private Runnable onCompleted; public MapToolConnection(ServerConfig config, LocalPlayer player) throws IOException { diff --git a/src/main/java/net/rptools/maptool/server/ClientHandshake.java b/src/main/java/net/rptools/maptool/server/ClientHandshake.java index 984e33e9db..13e88dcb67 100644 --- a/src/main/java/net/rptools/maptool/server/ClientHandshake.java +++ b/src/main/java/net/rptools/maptool/server/ClientHandshake.java @@ -45,7 +45,6 @@ import net.rptools.maptool.model.library.addon.AddOnLibraryImporter; import net.rptools.maptool.model.player.LocalPlayer; import net.rptools.maptool.model.player.LocalPlayerDatabase; -import net.rptools.maptool.model.player.Player; import net.rptools.maptool.model.player.Player.Role; import net.rptools.maptool.model.player.PlayerDatabaseFactory; import net.rptools.maptool.model.player.PlayerDatabaseFactory.PlayerDatabaseType; @@ -404,11 +403,6 @@ public Exception getException() { return exception; } - @Override - public Player getPlayer() { - return player; - } - private void closeEasyConnectDialog() { var dialog = getEasyConnectDialog(); if (dialog != null) { diff --git a/src/main/java/net/rptools/maptool/server/Handshake.java b/src/main/java/net/rptools/maptool/server/Handshake.java index 7cc26cdafd..de62e94160 100644 --- a/src/main/java/net/rptools/maptool/server/Handshake.java +++ b/src/main/java/net/rptools/maptool/server/Handshake.java @@ -15,11 +15,9 @@ package net.rptools.maptool.server; import java.util.concurrent.ExecutionException; -import net.rptools.clientserver.simple.MessageHandler; import net.rptools.clientserver.simple.connection.Connection; -import net.rptools.maptool.model.player.Player; -public interface Handshake extends MessageHandler { +public interface Handshake { /** * Returns if the handshake has been successful or not. @@ -50,13 +48,6 @@ public interface Handshake extends MessageHandler { */ Exception getException(); - /** - * Returns the player associated with the handshake. - * - * @return the player associated with the handshake. - */ - Player getPlayer(); - /** * Adds an observer to the handshake process. * diff --git a/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java b/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java index 30ac5b3c26..ff06af540f 100644 --- a/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java +++ b/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java @@ -187,16 +187,23 @@ public void removeObserver(ServerObserver observer) { @Override public void onCompleted(Handshake handshake) { + if (!(handshake instanceof ServerHandshake serverHandshake)) { + log.error("Got the wrong handshake type: {}", handshake.getClass()); + return; + } + handshake.removeObserver(this); if (handshake.isSuccessful()) { - Player player = handshake.getPlayer(); + Player player = serverHandshake.getPlayer(); if (player != null) { playerMap.put(handshake.getConnection().getId().toUpperCase(), player); } } else { var exception = handshake.getException(); - if (exception != null) log.error("Handshake failure: " + exception, exception); + if (exception != null) { + log.error("Handshake failure: " + exception, exception); + } } } } diff --git a/src/main/java/net/rptools/maptool/server/ServerHandshake.java b/src/main/java/net/rptools/maptool/server/ServerHandshake.java index 5fe1768808..ebf3314a5f 100644 --- a/src/main/java/net/rptools/maptool/server/ServerHandshake.java +++ b/src/main/java/net/rptools/maptool/server/ServerHandshake.java @@ -144,7 +144,11 @@ public synchronized Exception getException() { return exception; } - @Override + /** + * Returns the player associated with the handshake. + * + * @return the player associated with the handshake. + */ public synchronized Player getPlayer() { return player; } From 4e1e915a6b23d44e1285991dccc8ca313277dffd Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Fri, 5 Apr 2024 16:23:18 -0700 Subject: [PATCH 2/4] Clean up WebRTC code to not depend on MapTool specifics Both `WebRTCConnection` and `WebRTCServer` have had the following changes made: 1. Instead of accepting a `ServerConfig`, they both accept a `String` server name. This was the only part of the config used in the WebRTC code. 2. Instead of calling `MapTool.stopServer()` and `MapTool.showError()`, they now both have `Listener` interfaces that communicate the events that needed these actions take. The `ConnectionFactory` is responsible for hooking these up to the `MapTool` methods. I'm not a big fan of this approach, but I wanted to avoid complete reworks of server initialization and connection management, so this is what I went with. Also a bunch of `if` statements were gifted braces. --- .../clientserver/ConnectionFactory.java | 27 +++++++- .../simple/connection/WebRTCConnection.java | 61 +++++++++++++------ .../simple/server/WebRTCServer.java | 38 ++++++++---- 3 files changed, 92 insertions(+), 34 deletions(-) diff --git a/src/main/java/net/rptools/clientserver/ConnectionFactory.java b/src/main/java/net/rptools/clientserver/ConnectionFactory.java index 3a5302d2d3..5a4d711ddb 100644 --- a/src/main/java/net/rptools/clientserver/ConnectionFactory.java +++ b/src/main/java/net/rptools/clientserver/ConnectionFactory.java @@ -23,6 +23,7 @@ import net.rptools.clientserver.simple.server.Server; import net.rptools.clientserver.simple.server.SocketServer; import net.rptools.clientserver.simple.server.WebRTCServer; +import net.rptools.maptool.client.MapTool; import net.rptools.maptool.server.ServerConfig; public class ConnectionFactory { @@ -36,7 +37,15 @@ public Connection createConnection(String id, ServerConfig config) throws IOExce if (!config.getUseWebRTC() || config.isPersonalServer()) return new SocketConnection(id, config.getHostName(), config.getPort()); - return new WebRTCConnection(id, config); + return new WebRTCConnection( + id, + config.getServerName(), + new WebRTCConnection.Listener() { + @Override + public void onLoginError() { + MapTool.showError("Handshake.msg.playerAlreadyConnected"); + } + }); } public Server createServer( @@ -46,6 +55,20 @@ public Server createServer( return new SocketServer(config.getPort(), handshake, messageHandler); } - return new WebRTCServer(config, handshake, messageHandler); + return new WebRTCServer( + config.getServerName(), + handshake, + messageHandler, + new WebRTCServer.Listener() { + @Override + public void onLoginError() { + MapTool.showError("ServerDialog.error.serverAlreadyExists"); + } + + @Override + public void onUnexpectedClose() { + MapTool.stopServer(); + } + }); } } diff --git a/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java b/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java index 3c71a080bb..11783efaa2 100644 --- a/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java +++ b/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java @@ -22,8 +22,6 @@ import java.nio.ByteBuffer; import net.rptools.clientserver.simple.server.WebRTCServer; import net.rptools.clientserver.simple.webrtc.*; -import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.server.ServerConfig; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.java_websocket.client.WebSocketClient; @@ -31,12 +29,17 @@ public class WebRTCConnection extends AbstractConnection implements Connection, PeerConnectionObserver, RTCDataChannelObserver { + public interface Listener { + void onLoginError(); + } + private static final Logger log = LogManager.getLogger(WebRTCConnection.class); private final PeerConnectionFactory factory = new PeerConnectionFactory(); - private final ServerConfig config; + private final String serverName; private final String id; private final Gson gson = new Gson(); + private final Listener listener; private WebSocketClient signalingClient; // only set on server side private WebRTCServer server; @@ -49,9 +52,10 @@ public class WebRTCConnection extends AbstractConnection private Thread handleDisconnect; // used from client side - public WebRTCConnection(String id, ServerConfig config) { + public WebRTCConnection(String id, String serverName, Listener listener) { this.id = id; - this.config = config; + this.serverName = serverName; + this.listener = listener; init(); } @@ -59,7 +63,8 @@ public WebRTCConnection(String id, ServerConfig config) { public WebRTCConnection(OfferMessageDto message, WebRTCServer webRTCServer) { this.id = message.source; this.server = webRTCServer; - this.config = server.getConfig(); + this.serverName = server.getName(); + this.listener = () -> {}; this.signalingClient = server.getSignalingClient(); init(); @@ -90,7 +95,7 @@ public void onSuccess(RTCSessionDescription description) { @Override public void onSuccess() { var msg = new AnswerMessageDto(); - msg.source = server.getConfig().getServerName(); + msg.source = serverName; msg.destination = getId(); msg.answer = description; sendSignalingMessage(gson.toJson(msg)); @@ -116,9 +121,11 @@ private boolean isServerSide() { private String getSource() { // on server side the id is already user@server - if (isServerSide()) return getId(); + if (isServerSide()) { + return getId(); + } - return getId() + "@" + config.getServerName(); + return getId() + "@" + serverName; } private void startSignaling() { @@ -147,7 +154,9 @@ public void onMessage(String message) { public void onClose(int code, String reason, boolean remote) { lastError = "WebSocket closed: (" + code + ") " + reason; log.info(prefix() + lastError); - if (!isAlive()) fireDisconnectAsync(); + if (!isAlive()) { + fireDisconnectAsync(); + } } @Override @@ -208,7 +217,9 @@ public void sendMessage(Object channel, byte[] message) { @Override public boolean isAlive() { - if (peerConnection == null) return false; + if (peerConnection == null) { + return false; + } return switch (peerConnection.getConnectionState()) { case CONNECTED, DISCONNECTED -> true; @@ -269,7 +280,7 @@ public void onFailure(String error) { private void onLogin(LoginMessageDto message) { if (!message.success) { - MapTool.showError("Handshake.msg.playerAlreadyConnected"); + listener.onLoginError(); return; } @@ -293,7 +304,7 @@ public void onSuccess() { var msg = new OfferMessageDto(); msg.offer = description; msg.source = getSource(); - msg.destination = config.getServerName(); + msg.destination = serverName; sendSignalingMessage(gson.toJson(msg)); } @@ -366,10 +377,10 @@ public void onIceCandidate(RTCIceCandidate candidate) { var msg = new CandidateMessageDto(); if (isServerSide()) { - msg.source = config.getServerName(); + msg.source = serverName; msg.destination = getSource(); } else { - msg.destination = config.getServerName(); + msg.destination = serverName; msg.source = getSource(); } msg.candidate = candidate; @@ -460,7 +471,9 @@ public void onStateChange() { case OPEN -> { // connection established we don't need the signaling server anymore // for now disabled. We may get additional ice candidates. - if (!isServerSide() && signalingClient.isOpen()) signalingClient.close(); + if (!isServerSide() && signalingClient.isOpen()) { + signalingClient.close(); + } sendThread.start(); } @@ -483,7 +496,9 @@ public void onMessage(RTCDataChannelBuffer channelBuffer) { } var message = readMessage(channelBuffer.data); - if (message != null) dispatchCompressedMessage(id, message); + if (message != null) { + dispatchCompressedMessage(id, message); + } } private void fireDisconnectAsync() { @@ -491,7 +506,9 @@ private void fireDisconnectAsync() { new Thread( () -> { fireDisconnect(); - if (isServerSide()) server.clearClients(); + if (isServerSide()) { + server.clearClients(); + } }, "WebRTCConnection.handleDisconnect"); handleDisconnect.start(); @@ -500,9 +517,13 @@ private void fireDisconnectAsync() { @Override public void close() { // signalingClient should be closed if connection was established - if (!isServerSide() && signalingClient.isOpen()) signalingClient.close(); + if (!isServerSide() && signalingClient.isOpen()) { + signalingClient.close(); + } - if (sendThread.stopRequested) return; + if (sendThread.stopRequested) { + return; + } sendThread.requestStop(); if (peerConnection != null) { diff --git a/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java b/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java index 5954661f99..2b8aa5e3e4 100644 --- a/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java +++ b/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java @@ -25,8 +25,6 @@ import net.rptools.clientserver.simple.webrtc.LoginMessageDto; import net.rptools.clientserver.simple.webrtc.MessageDto; import net.rptools.clientserver.simple.webrtc.OfferMessageDto; -import net.rptools.maptool.client.MapTool; -import net.rptools.maptool.server.ServerConfig; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.java_websocket.client.WebSocketClient; @@ -35,8 +33,15 @@ public class WebRTCServer extends AbstractServer { private static final Logger log = LogManager.getLogger(WebRTCServer.class); + public interface Listener { + void onLoginError(); + + void onUnexpectedClose(); + } + + private final Listener listener; private WebSocketClient signalingClient; - private final ServerConfig config; + private final String serverName; private final Gson gson = new Gson(); private String lastError = null; private URI webSocketUri = null; @@ -48,9 +53,13 @@ public class WebRTCServer extends AbstractServer { private boolean disconnectExpected; public WebRTCServer( - ServerConfig config, HandshakeProvider handshake, MessageHandler messageHandler) { + String serverName, + HandshakeProvider handshake, + MessageHandler messageHandler, + Listener listener) { super(handshake, messageHandler); - this.config = config; + this.listener = listener; + this.serverName = serverName; try { webSocketUri = new URI(WebSocketUrl); @@ -72,7 +81,7 @@ public void onOpen(ServerHandshake handshakeData) { reconnectCounter = 30; log.info("S WebSocket connected\n"); var msg = new LoginMessageDto(); - msg.source = config.getServerName(); + msg.source = serverName; sendSignalingMessage(gson.toJson(msg)); } @@ -86,12 +95,17 @@ public void onMessage(String message) { public void onClose(int code, String reason, boolean remote) { lastError = "WebSocket closed: remote:" + remote + " (" + code + ") " + reason; log.info("S " + lastError); - if (disconnectExpected) return; + if (disconnectExpected) { + return; + } // if the connection get closed remotely the rptools.net server disconnected. Try to // reconnect. - if (reconnectCounter > 0) retryConnect(); - else MapTool.stopServer(); + if (reconnectCounter > 0) { + retryConnect(); + } else { + listener.onUnexpectedClose(); + } } @Override @@ -111,7 +125,7 @@ private void handleSignalingMessage(String message) { case "login" -> { var loginMsg = gson.fromJson(message, LoginMessageDto.class); if (!loginMsg.success) { - MapTool.showError("ServerDialog.error.serverAlreadyExists"); + listener.onLoginError(); } } case "offer" -> { @@ -131,8 +145,8 @@ public WebSocketClient getSignalingClient() { return signalingClient; } - public ServerConfig getConfig() { - return config; + public String getName() { + return serverName; } public void onDataChannelOpened(WebRTCConnection connection) { From 8d3cd771cb049baed2694e749a5d97ee2633f70a Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Sat, 6 Apr 2024 21:26:41 -0700 Subject: [PATCH 3/4] Avoid exposing webrtc library specifics in WebRTCConnection This avoids putting `PeerConnectionObserver` and `RTCDataChannelObserver` in the API of `WebRTCConnection`. Not doing this will require subtle dependency requirements once in a separate project. --- .../simple/connection/WebRTCConnection.java | 352 +++++++++--------- 1 file changed, 177 insertions(+), 175 deletions(-) diff --git a/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java b/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java index 11783efaa2..7f9081972b 100644 --- a/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java +++ b/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java @@ -27,14 +27,15 @@ import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; -public class WebRTCConnection extends AbstractConnection - implements Connection, PeerConnectionObserver, RTCDataChannelObserver { +public class WebRTCConnection extends AbstractConnection implements Connection { public interface Listener { void onLoginError(); } private static final Logger log = LogManager.getLogger(WebRTCConnection.class); + private final PeerConnectionObserver peerConnectionObserver = new PeerConnectionObserverImpl(); + private final RTCDataChannelObserver rtcDataChannelObserver = new RTCDataChannelObserverImpl(); private final PeerConnectionFactory factory = new PeerConnectionFactory(); private final String serverName; private final String id; @@ -68,7 +69,7 @@ public WebRTCConnection(OfferMessageDto message, WebRTCServer webRTCServer) { this.signalingClient = server.getSignalingClient(); init(); - peerConnection = factory.createPeerConnection(rtcConfig, this); + peerConnection = factory.createPeerConnection(rtcConfig, peerConnectionObserver); peerConnection.setRemoteDescription( message.offer, new SetSessionDescriptionObserver() { @@ -284,11 +285,11 @@ private void onLogin(LoginMessageDto message) { return; } - peerConnection = factory.createPeerConnection(rtcConfig, this); + peerConnection = factory.createPeerConnection(rtcConfig, peerConnectionObserver); var initDict = new RTCDataChannelInit(); localDataChannel = peerConnection.createDataChannel("myDataChannel", initDict); - localDataChannel.registerObserver(this); + localDataChannel.registerObserver(rtcDataChannelObserver); var offerOptions = new RTCOfferOptions(); peerConnection.createOffer( @@ -326,181 +327,11 @@ private String prefix() { return isServerSide() ? "S " : "C "; } - @Override - public void onSignalingChange(RTCSignalingState state) { - // set thread name for better logs. - Thread.currentThread().setName("WebRTCConnection.WebRTCThread_" + getId()); - log.info(prefix() + "PeerConnection.onSignalingChange: " + state); - } - - @Override - public void onConnectionChange(RTCPeerConnectionState state) { - log.info(prefix() + "PeerConnection.onConnectionChange " + state); - switch (state) { - case FAILED -> { - lastError = "PeerConnection failed"; - peerConnection = null; - fireDisconnectAsync(); - } - case CONNECTED -> { - if (hasMoreMessages()) { - synchronized (sendThread) { - sendThread.notify(); - } - } - } - } - } - - @Override - public void onIceConnectionChange(RTCIceConnectionState state) { - log.info(prefix() + "PeerConnection.onIceConnectionChange " + state); - } - - @Override - public void onStandardizedIceConnectionChange(RTCIceConnectionState state) { - log.info(prefix() + "PeerConnection.onStandardizedIceConnectionChange " + state); - } - - @Override - public void onIceConnectionReceivingChange(boolean receiving) { - log.info(prefix() + "PeerConnection.onIceConnectionReceivingChange " + receiving); - } - - @Override - public void onIceGatheringChange(RTCIceGatheringState state) { - log.info(prefix() + "PeerConnection.onIceGatheringChange " + state); - } - - @Override - public void onIceCandidate(RTCIceCandidate candidate) { - var msg = new CandidateMessageDto(); - - if (isServerSide()) { - msg.source = serverName; - msg.destination = getSource(); - } else { - msg.destination = serverName; - msg.source = getSource(); - } - msg.candidate = candidate; - sendSignalingMessage(gson.toJson(msg)); - } - - @Override - public void onIceCandidateError(RTCPeerConnectionIceErrorEvent event) { - log.debug( - prefix() - + "PeerConnection.onIceCandidateError: code:" - + event.getErrorCode() - + " url: " - + event.getUrl() - + " address/port: " - + event.getAddress() - + ":" - + event.getPort() - + " text: " - + event.getErrorText()); - } - - @Override - public void onIceCandidatesRemoved(RTCIceCandidate[] candidates) { - log.info(prefix() + "PeerConnection.onIceCandidatesRemoved"); - } - - @Override - public void onAddStream(MediaStream stream) { - log.info(prefix() + "PeerConnection.onAddStream"); - } - - @Override - public void onRemoveStream(MediaStream stream) { - log.info(prefix() + "PeerConnection.onRemoveStream"); - } - - @Override - public void onDataChannel(RTCDataChannel newDataChannel) { - log.info(prefix() + "PeerConnection.onDataChannel"); - this.localDataChannel = newDataChannel; - localDataChannel.registerObserver(this); - - if (isServerSide()) { - server.onDataChannelOpened(this); - } - } - - @Override - public void onRenegotiationNeeded() { - // set thread name for better logs - Thread.currentThread().setName("WebRTCConnection.WebRTCThread_" + getId()); - log.info(prefix() + "PeerConnection.onRenegotiationNeeded"); - } - - @Override - public void onAddTrack(RTCRtpReceiver receiver, MediaStream[] mediaStreams) { - log.info(prefix() + "PeerConnection.onTrack(multiple Streams)"); - } - - @Override - public void onRemoveTrack(RTCRtpReceiver receiver) { - log.info(prefix() + "PeerConnection.onRemoveTrack"); - } - - @Override - public void onTrack(RTCRtpTransceiver transceiver) { - log.info(prefix() + "PeerConnection.onTrack"); - } - public void addIceCandidate(RTCIceCandidate candidate) { log.info(prefix() + "PeerConnection.addIceCandidate: " + candidate.toString()); peerConnection.addIceCandidate(candidate); } - // dataChannel - @Override - public void onBufferedAmountChange(long previousAmount) { - log.info(prefix() + "dataChannel onBufferedAmountChange " + previousAmount); - } - - // dataChannel - @Override - public void onStateChange() { - var state = localDataChannel.getState(); - log.info(prefix() + "localDataChannel onStateChange " + state); - switch (state) { - case OPEN -> { - // connection established we don't need the signaling server anymore - // for now disabled. We may get additional ice candidates. - if (!isServerSide() && signalingClient.isOpen()) { - signalingClient.close(); - } - - sendThread.start(); - } - case CLOSED -> { - close(); - fireDisconnectAsync(); - } - } - } - - // dataChannel - @Override - public void onMessage(RTCDataChannelBuffer channelBuffer) { - log.debug( - prefix() + "localDataChannel onMessage: got " + channelBuffer.data.capacity() + " bytes"); - - if (Thread.currentThread().getContextClassLoader() == null) { - ClassLoader cl = ClassLoader.getSystemClassLoader(); - Thread.currentThread().setContextClassLoader(cl); - } - - var message = readMessage(channelBuffer.data); - if (message != null) { - dispatchCompressedMessage(id, message); - } - } - private void fireDisconnectAsync() { handleDisconnect = new Thread( @@ -606,4 +437,175 @@ public void run() { log.debug(prefix() + " sendThread ended"); } } + + private final class PeerConnectionObserverImpl implements PeerConnectionObserver { + @Override + public void onIceCandidate(RTCIceCandidate candidate) { + var msg = new CandidateMessageDto(); + + if (isServerSide()) { + msg.source = serverName; + msg.destination = getSource(); + } else { + msg.destination = serverName; + msg.source = getSource(); + } + msg.candidate = candidate; + sendSignalingMessage(gson.toJson(msg)); + } + + @Override + public void onAddStream(MediaStream stream) { + log.info(prefix() + "PeerConnection.onAddStream"); + } + + @Override + public void onAddTrack(RTCRtpReceiver receiver, MediaStream[] mediaStreams) { + log.info(prefix() + "PeerConnection.onTrack(multiple Streams)"); + } + + @Override + public void onConnectionChange(RTCPeerConnectionState state) { + log.info(prefix() + "PeerConnection.onConnectionChange " + state); + switch (state) { + case FAILED -> { + lastError = "PeerConnection failed"; + peerConnection = null; + fireDisconnectAsync(); + } + case CONNECTED -> { + if (hasMoreMessages()) { + synchronized (sendThread) { + sendThread.notify(); + } + } + } + } + } + + @Override + public void onDataChannel(RTCDataChannel newDataChannel) { + log.info(prefix() + "PeerConnection.onDataChannel"); + localDataChannel = newDataChannel; + localDataChannel.registerObserver(rtcDataChannelObserver); + + if (isServerSide()) { + server.onDataChannelOpened(WebRTCConnection.this); + } + } + + @Override + public void onIceCandidateError(RTCPeerConnectionIceErrorEvent event) { + log.debug( + prefix() + + "PeerConnection.onIceCandidateError: code:" + + event.getErrorCode() + + " url: " + + event.getUrl() + + " address/port: " + + event.getAddress() + + ":" + + event.getPort() + + " text: " + + event.getErrorText()); + } + + @Override + public void onIceCandidatesRemoved(RTCIceCandidate[] candidates) { + log.info(prefix() + "PeerConnection.onIceCandidatesRemoved"); + } + + @Override + public void onIceConnectionChange(RTCIceConnectionState state) { + log.info(prefix() + "PeerConnection.onIceConnectionChange " + state); + } + + @Override + public void onIceConnectionReceivingChange(boolean receiving) { + log.info(prefix() + "PeerConnection.onIceConnectionReceivingChange " + receiving); + } + + @Override + public void onIceGatheringChange(RTCIceGatheringState state) { + log.info(prefix() + "PeerConnection.onIceGatheringChange " + state); + } + + @Override + public void onRemoveStream(MediaStream stream) { + log.info(prefix() + "PeerConnection.onRemoveStream"); + } + + @Override + public void onRemoveTrack(RTCRtpReceiver receiver) { + log.info(prefix() + "PeerConnection.onRemoveTrack"); + } + + @Override + public void onRenegotiationNeeded() { + // set thread name for better logs + Thread.currentThread().setName("WebRTCConnection.WebRTCThread_" + getId()); + log.info(prefix() + "PeerConnection.onRenegotiationNeeded"); + } + + @Override + public void onSignalingChange(RTCSignalingState state) { + // set thread name for better logs. + Thread.currentThread().setName("WebRTCConnection.WebRTCThread_" + getId()); + log.info(prefix() + "PeerConnection.onSignalingChange: " + state); + } + + @Override + public void onStandardizedIceConnectionChange(RTCIceConnectionState state) { + log.info(prefix() + "PeerConnection.onStandardizedIceConnectionChange " + state); + } + + @Override + public void onTrack(RTCRtpTransceiver transceiver) { + log.info(prefix() + "PeerConnection.onTrack"); + } + } + + private final class RTCDataChannelObserverImpl implements RTCDataChannelObserver { + @Override + public void onBufferedAmountChange(long previousAmount) { + log.info(prefix() + "dataChannel onBufferedAmountChange " + previousAmount); + } + + @Override + public void onStateChange() { + var state = localDataChannel.getState(); + log.info(prefix() + "localDataChannel onStateChange " + state); + switch (state) { + case OPEN -> { + // connection established we don't need the signaling server anymore + // for now disabled. We may get additional ice candidates. + if (!isServerSide() && signalingClient.isOpen()) { + signalingClient.close(); + } + + sendThread.start(); + } + case CLOSED -> { + close(); + fireDisconnectAsync(); + } + } + } + + @Override + public void onMessage(RTCDataChannelBuffer channelBuffer) { + log.debug( + prefix() + "localDataChannel onMessage: got " + channelBuffer.data.capacity() + " bytes"); + + if (Thread.currentThread().getContextClassLoader() == null) { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + Thread.currentThread().setContextClassLoader(cl); + } + + var message = readMessage(channelBuffer.data); + if (message != null) { + dispatchCompressedMessage(id, message); + } + } + } } From dca7107b0abcd8b841e89591dd480a50244069ab Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Fri, 5 Apr 2024 14:11:08 -0700 Subject: [PATCH 4/4] Move clientserver code into a subproject Left behind was `ConnectionFactory` as it is really a MapTool-specific tool for building connections and servers rather than a part of the general client-server logic itself. Also pulled in was `Handshake` and `HandshakeObserver` since they are used in the client-server and are an important part of the process (the implementations were left behind though). Common build configurations wered moved into a `shared.gradle` file applied to the root project and subprojects. Dependencies specific to the clientserver subproject were moved out of the root project to keep things clear. --- build.gradle | 59 ++++--------------- buildSrc/shared.gradle | 35 +++++++++++ clientserver/build.gradle | 33 +++++++++++ .../clientserver/ActivityListener.java | 0 .../simple/DisconnectHandler.java | 0 .../clientserver/simple}/Handshake.java | 2 +- .../simple}/HandshakeObserver.java | 2 +- .../clientserver/simple/MessageHandler.java | 0 .../simple/connection/AbstractConnection.java | 0 .../simple/connection/Connection.java | 0 .../simple/connection/SocketConnection.java | 0 .../simple/connection/WebRTCConnection.java | 0 .../simple/server/AbstractServer.java | 4 +- .../simple/server/HandshakeProvider.java | 2 +- .../clientserver/simple/server/Server.java | 0 .../simple/server/ServerObserver.java | 0 .../simple/server/SocketServer.java | 0 .../simple/server/WebRTCServer.java | 0 .../simple/webrtc/AnswerMessageDto.java | 0 .../simple/webrtc/CandidateMessageDto.java | 0 .../simple/webrtc/LoginMessageDto.java | 0 .../simple/webrtc/MessageDto.java | 0 .../simple/webrtc/OfferMessageDto.java | 0 settings.gradle | 1 + .../maptool/server/ClientHandshake.java | 2 + .../server/MapToolServerConnection.java | 2 + .../maptool/server/ServerHandshake.java | 2 + 27 files changed, 92 insertions(+), 52 deletions(-) create mode 100644 buildSrc/shared.gradle create mode 100644 clientserver/build.gradle rename {src => clientserver/src}/main/java/net/rptools/clientserver/ActivityListener.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/DisconnectHandler.java (100%) rename {src/main/java/net/rptools/maptool/server => clientserver/src/main/java/net/rptools/clientserver/simple}/Handshake.java (98%) rename {src/main/java/net/rptools/maptool/server => clientserver/src/main/java/net/rptools/clientserver/simple}/HandshakeObserver.java (94%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/MessageHandler.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/connection/AbstractConnection.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/connection/Connection.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/server/AbstractServer.java (97%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java (94%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/server/Server.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/server/ServerObserver.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/server/SocketServer.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/webrtc/AnswerMessageDto.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/webrtc/CandidateMessageDto.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/webrtc/LoginMessageDto.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/webrtc/MessageDto.java (100%) rename {src => clientserver/src}/main/java/net/rptools/clientserver/simple/webrtc/OfferMessageDto.java (100%) diff --git a/build.gradle b/build.gradle index 9d2768a141..e0ff2138fe 100644 --- a/build.gradle +++ b/build.gradle @@ -18,21 +18,23 @@ plugins { id "base" id "java" id "org.ajoberstar.grgit" version "5.2.1" - id "com.diffplug.spotless" version "6.25.0" id 'org.openjfx.javafxplugin' version '0.0.13' id 'org.beryx.runtime' version '1.13.0' id "com.google.protobuf" version "0.9.4" id 'com.github.johnrengelman.shadow' version '8.1.1' + + id "com.diffplug.spotless" version "6.25.0" apply false +} + +allprojects { + apply plugin: "com.diffplug.spotless" } +apply from: rootProject.file('buildSrc/shared.gradle') + // Definitions defaultTasks 'clean', 'build' -java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - def javaArgs = [ "-Xss8M", "-Dsun.java2d.d3d=false", "-Dsentry.environment=Production", "-Dfile.encoding=UTF-8", "-Dpolyglot.engine.WarnInterpreterOnly=false", @@ -112,32 +114,18 @@ ext { println "OS Detected: " + osdetector.os } + spotless { java { - target project.fileTree(project.rootDir) { + target project.fileTree(project.projectDir) { include 'src/**/*.java' exclude '**/JTextAreaAppender.java' exclude 'src/main/java/net/rptools/maptool/client/ui/themes/Flat*ContrastIJTheme.java' exclude 'src/main/java/net/rptools/maptool/client/ui/themes/Utils.java' } - licenseHeaderFile 'spotless.license.java' - toggleOffOn() - - // Now using the Google Java style guide - googleJavaFormat("1.17.0") - } - - format 'misc', { - target '**/*.gradle', '**/.gitignore' - - // spotless has built-in rules for most basic formatting tasks - trimTrailingWhitespace() - // or spaces. Takes an integer argument if you don't like 4 - indentWithSpaces(4) } } - // org.openjfx.javafxplugin javafx { version = '22' @@ -325,23 +313,13 @@ runtime { } } } -// In this section you declare where to find the dependencies of your project -repositories { - // Use 'jcenter' for resolving your dependencies. - // You can declare any Maven/Ivy/file repository here. - mavenLocal() - mavenCentral() - maven { url = 'https://maptool.craigs-stuff.net/repo/' } - maven { url = 'https://jitpack.io' } - maven { url "https://www.jetbrains.com/intellij-repository/releases" } - maven { url "https://cache-redirector.jetbrains.com/intellij-dependencies" } -} - // In this section you declare the dependencies for your production and test code dependencies { forms group: 'com.jetbrains.intellij.java', name: 'java-compiler-ant-tasks', version: '233.14475.56' + implementation project(':clientserver') + implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.22.1' implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.22.1' implementation group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.20.0' // Bridges v1 to v2 for other code in other libs @@ -492,16 +470,6 @@ dependencies { // Noise Generator implementation 'com.github.cwisniew:NoiseLib:1.0.0' // The most recent version, 1.0.0 is build for a later java version: major version 55 is newer than 54, the highest major version supported by this compiler - // webrtc - implementation group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.5.6' - implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0' - if (osdetector.os.is('windows')) - implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0:windows-x86_64' - else if (osdetector.os.is('osx')) - implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0:macos-x86_64' - else if (osdetector.os.is('linux')) - implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0:linux-x86_64' - // protobuf implementation "io.grpc:grpc-protobuf:1.61.1" implementation "com.google.protobuf:protobuf-java-util:3.25.2" @@ -516,9 +484,6 @@ dependencies { implementation 'org.jsoup:jsoup:1.17.2' // eventbus implementation 'com.google.guava:guava:33.0.0-jre' - // compression of messages between client and server - implementation 'org.apache.commons:commons-compress:1.26.0' - implementation 'com.github.luben:zstd-jni:1.5.5-11' // intellij forms runtime implementation 'com.jetbrains.intellij.java:java-gui-forms-rt:241.12019' // layout for forms created in code diff --git a/buildSrc/shared.gradle b/buildSrc/shared.gradle new file mode 100644 index 0000000000..3fd4380b24 --- /dev/null +++ b/buildSrc/shared.gradle @@ -0,0 +1,35 @@ +// In this section you declare where to find the dependencies of your project +repositories { + mavenLocal() + mavenCentral() + maven { url = 'https://maptool.craigs-stuff.net/repo/' } + maven { url = 'https://jitpack.io' } + maven { url "https://www.jetbrains.com/intellij-repository/releases" } + maven { url "https://cache-redirector.jetbrains.com/intellij-dependencies" } +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + +spotless { + java { + target project.fileTree(project.projectDir) { + include 'src/**/*.java' + } + licenseHeaderFile rootProject.file('spotless.license.java') + toggleOffOn() + // Now using the Google Java style guide + googleJavaFormat("1.17.0") + } + + format 'misc', { + target '**/*.gradle', '**/.gitignore' + + // spotless has built-in rules for most basic formatting tasks + trimTrailingWhitespace() + // or spaces. Takes an integer argument if you don't like 4 + indentWithSpaces(4) + } +} \ No newline at end of file diff --git a/clientserver/build.gradle b/clientserver/build.gradle new file mode 100644 index 0000000000..d111e207d9 --- /dev/null +++ b/clientserver/build.gradle @@ -0,0 +1,33 @@ +plugins { + id "base" + id "java-library" +} + +apply from: rootProject.file('buildSrc/shared.gradle') + +// In this section you declare the dependencies for your production and test code +dependencies { + implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.22.1' + implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.22.1' + implementation group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.20.0' // Bridges v1 to v2 for other code in other libs + implementation group: 'org.slf4j', name: 'slf4j-simple', version: '2.0.12' + implementation group: 'commons-logging', name: 'commons-logging', version: '1.3.0' + + // Better JSON functions... + implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' // https://mvnrepository.com/artifact/com.google.code.gson/gson + + // webrtc + implementation group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.5.6' + // Needs to be API since WebRTCConnection implements PeerConnectionObserver and RTCDataChannelObserver. + implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0' + if (osdetector.os.is('windows')) + implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0:windows-x86_64' + else if (osdetector.os.is('osx')) + implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0:macos-x86_64' + else if (osdetector.os.is('linux')) + implementation 'dev.onvoid.webrtc:webrtc-java:0.8.0:linux-x86_64' + + // compression of messages between client and server + implementation 'org.apache.commons:commons-compress:1.26.0' + implementation 'com.github.luben:zstd-jni:1.5.5-11' +} diff --git a/src/main/java/net/rptools/clientserver/ActivityListener.java b/clientserver/src/main/java/net/rptools/clientserver/ActivityListener.java similarity index 100% rename from src/main/java/net/rptools/clientserver/ActivityListener.java rename to clientserver/src/main/java/net/rptools/clientserver/ActivityListener.java diff --git a/src/main/java/net/rptools/clientserver/simple/DisconnectHandler.java b/clientserver/src/main/java/net/rptools/clientserver/simple/DisconnectHandler.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/DisconnectHandler.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/DisconnectHandler.java diff --git a/src/main/java/net/rptools/maptool/server/Handshake.java b/clientserver/src/main/java/net/rptools/clientserver/simple/Handshake.java similarity index 98% rename from src/main/java/net/rptools/maptool/server/Handshake.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/Handshake.java index de62e94160..72a6b7d5b1 100644 --- a/src/main/java/net/rptools/maptool/server/Handshake.java +++ b/clientserver/src/main/java/net/rptools/clientserver/simple/Handshake.java @@ -12,7 +12,7 @@ * and specifically the Affero license * text at . */ -package net.rptools.maptool.server; +package net.rptools.clientserver.simple; import java.util.concurrent.ExecutionException; import net.rptools.clientserver.simple.connection.Connection; diff --git a/src/main/java/net/rptools/maptool/server/HandshakeObserver.java b/clientserver/src/main/java/net/rptools/clientserver/simple/HandshakeObserver.java similarity index 94% rename from src/main/java/net/rptools/maptool/server/HandshakeObserver.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/HandshakeObserver.java index e8e62d66a0..e81393ba56 100644 --- a/src/main/java/net/rptools/maptool/server/HandshakeObserver.java +++ b/clientserver/src/main/java/net/rptools/clientserver/simple/HandshakeObserver.java @@ -12,7 +12,7 @@ * and specifically the Affero license * text at . */ -package net.rptools.maptool.server; +package net.rptools.clientserver.simple; public interface HandshakeObserver { diff --git a/src/main/java/net/rptools/clientserver/simple/MessageHandler.java b/clientserver/src/main/java/net/rptools/clientserver/simple/MessageHandler.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/MessageHandler.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/MessageHandler.java diff --git a/src/main/java/net/rptools/clientserver/simple/connection/AbstractConnection.java b/clientserver/src/main/java/net/rptools/clientserver/simple/connection/AbstractConnection.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/connection/AbstractConnection.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/connection/AbstractConnection.java diff --git a/src/main/java/net/rptools/clientserver/simple/connection/Connection.java b/clientserver/src/main/java/net/rptools/clientserver/simple/connection/Connection.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/connection/Connection.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/connection/Connection.java diff --git a/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java b/clientserver/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/connection/SocketConnection.java diff --git a/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java b/clientserver/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/connection/WebRTCConnection.java diff --git a/src/main/java/net/rptools/clientserver/simple/server/AbstractServer.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/AbstractServer.java similarity index 97% rename from src/main/java/net/rptools/clientserver/simple/server/AbstractServer.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/server/AbstractServer.java index b966028f2a..e93376b8b5 100644 --- a/src/main/java/net/rptools/clientserver/simple/server/AbstractServer.java +++ b/clientserver/src/main/java/net/rptools/clientserver/simple/server/AbstractServer.java @@ -17,10 +17,10 @@ import java.util.*; import java.util.concurrent.ExecutionException; import net.rptools.clientserver.simple.DisconnectHandler; +import net.rptools.clientserver.simple.Handshake; +import net.rptools.clientserver.simple.HandshakeObserver; import net.rptools.clientserver.simple.MessageHandler; import net.rptools.clientserver.simple.connection.Connection; -import net.rptools.maptool.server.Handshake; -import net.rptools.maptool.server.HandshakeObserver; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/src/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java similarity index 94% rename from src/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java index e9444833fb..1a073ce58a 100644 --- a/src/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java +++ b/clientserver/src/main/java/net/rptools/clientserver/simple/server/HandshakeProvider.java @@ -14,8 +14,8 @@ */ package net.rptools.clientserver.simple.server; +import net.rptools.clientserver.simple.Handshake; import net.rptools.clientserver.simple.connection.Connection; -import net.rptools.maptool.server.Handshake; public interface HandshakeProvider { Handshake getConnectionHandshake(Connection conn); diff --git a/src/main/java/net/rptools/clientserver/simple/server/Server.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/Server.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/server/Server.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/server/Server.java diff --git a/src/main/java/net/rptools/clientserver/simple/server/ServerObserver.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/ServerObserver.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/server/ServerObserver.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/server/ServerObserver.java diff --git a/src/main/java/net/rptools/clientserver/simple/server/SocketServer.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/SocketServer.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/server/SocketServer.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/server/SocketServer.java diff --git a/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java b/clientserver/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/server/WebRTCServer.java diff --git a/src/main/java/net/rptools/clientserver/simple/webrtc/AnswerMessageDto.java b/clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/AnswerMessageDto.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/webrtc/AnswerMessageDto.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/AnswerMessageDto.java diff --git a/src/main/java/net/rptools/clientserver/simple/webrtc/CandidateMessageDto.java b/clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/CandidateMessageDto.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/webrtc/CandidateMessageDto.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/CandidateMessageDto.java diff --git a/src/main/java/net/rptools/clientserver/simple/webrtc/LoginMessageDto.java b/clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/LoginMessageDto.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/webrtc/LoginMessageDto.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/LoginMessageDto.java diff --git a/src/main/java/net/rptools/clientserver/simple/webrtc/MessageDto.java b/clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/MessageDto.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/webrtc/MessageDto.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/MessageDto.java diff --git a/src/main/java/net/rptools/clientserver/simple/webrtc/OfferMessageDto.java b/clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/OfferMessageDto.java similarity index 100% rename from src/main/java/net/rptools/clientserver/simple/webrtc/OfferMessageDto.java rename to clientserver/src/main/java/net/rptools/clientserver/simple/webrtc/OfferMessageDto.java diff --git a/settings.gradle b/settings.gradle index bd472eecbf..440cc0f959 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,3 +16,4 @@ include 'services:webservice' */ rootProject.name = 'MapTool' +include ':clientserver' \ No newline at end of file diff --git a/src/main/java/net/rptools/maptool/server/ClientHandshake.java b/src/main/java/net/rptools/maptool/server/ClientHandshake.java index 13e88dcb67..9531280dbc 100644 --- a/src/main/java/net/rptools/maptool/server/ClientHandshake.java +++ b/src/main/java/net/rptools/maptool/server/ClientHandshake.java @@ -31,6 +31,8 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.swing.*; +import net.rptools.clientserver.simple.Handshake; +import net.rptools.clientserver.simple.HandshakeObserver; import net.rptools.clientserver.simple.MessageHandler; import net.rptools.clientserver.simple.connection.Connection; import net.rptools.lib.MD5Key; diff --git a/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java b/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java index ff06af540f..edd1a31cd5 100644 --- a/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java +++ b/src/main/java/net/rptools/maptool/server/MapToolServerConnection.java @@ -18,6 +18,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.rptools.clientserver.ConnectionFactory; +import net.rptools.clientserver.simple.Handshake; +import net.rptools.clientserver.simple.HandshakeObserver; import net.rptools.clientserver.simple.connection.Connection; import net.rptools.clientserver.simple.server.HandshakeProvider; import net.rptools.clientserver.simple.server.Server; diff --git a/src/main/java/net/rptools/maptool/server/ServerHandshake.java b/src/main/java/net/rptools/maptool/server/ServerHandshake.java index ebf3314a5f..76b5cfb5a0 100644 --- a/src/main/java/net/rptools/maptool/server/ServerHandshake.java +++ b/src/main/java/net/rptools/maptool/server/ServerHandshake.java @@ -29,6 +29,8 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.swing.SwingUtilities; +import net.rptools.clientserver.simple.Handshake; +import net.rptools.clientserver.simple.HandshakeObserver; import net.rptools.clientserver.simple.MessageHandler; import net.rptools.clientserver.simple.connection.Connection; import net.rptools.lib.MD5Key;