From 2e15ae7268534e54e18b604eff5aa0bfa995401a Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 18 May 2018 08:38:38 -0500 Subject: [PATCH] Updated client-holocore to use new pswgcommon utilities --- .gitmodules | 3 - ClientHolocore.jar | Bin 82789 -> 0 bytes PSWGCommon | 1 - build.gradle | 25 +- settings.gradle | 2 +- src/com/projectswg/connection/UDPServer.java | 277 ------------------ .../connection/HolocoreProtocol.java | 0 .../projectswg/connection/HolocoreSocket.java | 69 ++--- .../projectswg/connection/SWGProtocol.java | 0 .../ServerConnectionChangedReason.java | 0 .../connection/ServerConnectionStatus.java | 0 .../connection/packets/RawPacket.java | 0 12 files changed, 34 insertions(+), 343 deletions(-) delete mode 100644 ClientHolocore.jar delete mode 160000 PSWGCommon delete mode 100644 src/com/projectswg/connection/UDPServer.java rename src/{ => main/java}/com/projectswg/connection/HolocoreProtocol.java (100%) rename src/{ => main/java}/com/projectswg/connection/HolocoreSocket.java (78%) rename src/{ => main/java}/com/projectswg/connection/SWGProtocol.java (100%) rename src/{ => main/java}/com/projectswg/connection/ServerConnectionChangedReason.java (100%) rename src/{ => main/java}/com/projectswg/connection/ServerConnectionStatus.java (100%) rename src/{ => main/java}/com/projectswg/connection/packets/RawPacket.java (100%) diff --git a/.gitmodules b/.gitmodules index ee4cb66..856c61c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "pswgcommon"] path = pswgcommon url = git@bitbucket.org:projectswg/pswgcommon.git -[submodule "PSWGCommon"] - path = PSWGCommon - url = git@bitbucket.org:projectswg/pswgcommon.git diff --git a/ClientHolocore.jar b/ClientHolocore.jar deleted file mode 100644 index 23049862e99fb5d51f703183a632af3cbd174c0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82789 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%0DgQI=P){Bf8X4u2NaxTRre0I^Azs%TA9 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. * -* * -***********************************************************************************/ -package com.projectswg.connection; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Queue; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * This class represents a UDP server that listens for packets and - * will call the callback when it receives one - */ -class UDPServer { - - private Object waitingForPacket = new Object(); - - private final DatagramSocket socket; - private final UDPUpdater updater; - private final Queue inbound; - private final int packetSize; - private UDPCallback callback; - private int port; - - public UDPServer(int port) throws SocketException { - this(port, 1024); - } - - public UDPServer(int port, int packetSize) throws SocketException { - this(null, port, packetSize); - } - - public UDPServer(InetAddress bindAddr, int port, int packetSize) throws SocketException { - this.callback = null; - this.packetSize = packetSize; - inbound = new LinkedBlockingQueue(); - if (port > 0) { - if (bindAddr == null) - socket = new DatagramSocket(port); - else - socket = new DatagramSocket(port, bindAddr); - } else - socket = new DatagramSocket(); - this.port = socket.getLocalPort(); - updater = new UDPUpdater(); - updater.start(); - } - - public void close() { - if (updater != null) - updater.stop(); - if (socket != null) - socket.close(); - } - - public UDPPacket receive() { - return inbound.poll(); - } - - public int packetCount() { - return inbound.size(); - } - - public int getPort() { - return port; - } - - public boolean isRunning() { - return updater != null && updater.isRunning(); - } - - public void waitForPacket() { - synchronized (waitingForPacket) { - try { - while (inbound.isEmpty()) { - waitingForPacket.wait(); - } - } catch (InterruptedException e) { - - } - } - } - - public boolean waitForPacket(long timeout) { - long start = System.nanoTime(); - synchronized (waitingForPacket) { - try { - while (inbound.isEmpty()) { - long waitTime = (long) (timeout - (System.nanoTime() - start)/1E6 + 0.5); - if (waitTime <= 0) - return false; - waitingForPacket.wait(waitTime); - } - return true; - } catch (InterruptedException e) { - - } - } - return false; - } - - public boolean send(int port, InetAddress addr, byte [] data) { - try { - socket.send(new DatagramPacket(data, data.length, addr, port)); - return true; - } catch (IOException e) { - String msg = e.getMessage(); - if (msg != null && msg.startsWith("Socket") && msg.endsWith("closed")) - return false; - else - e.printStackTrace(); - return false; - } - } - - public boolean send(int port, String addr, byte [] data) { - try { - return send(port, InetAddress.getByName(addr), data); - } catch (UnknownHostException e) { - e.printStackTrace(); - } - return false; - } - - public boolean send(InetSocketAddress addr, byte [] data) { - return send(addr.getPort(), addr.getAddress(), data); - } - - public void setCallback(UDPCallback callback) { - this.callback = callback; - } - - public void removeCallback() { - callback = null; - } - - public interface UDPCallback { - public void onReceivedPacket(UDPPacket packet); - } - - public static class UDPPacket { - private final byte [] data; - private final InetAddress addr; - private final int port; - - public UDPPacket(InetAddress addr, int port, byte [] data) { - this.data = data; - this.addr = addr; - this.port = port; - } - - public InetAddress getAddress() { - return addr; - } - - public int getPort() { - return port; - } - - public byte [] getData() { - return data; - } - - public int getLength() { - return data.length; - } - } - - private class UDPUpdater implements Runnable { - - private final Thread thread; - private final byte [] dataBuffer; - private boolean running; - - public UDPUpdater() { - thread = new Thread(this); - thread.setName("UDPServer Port#" + port); - dataBuffer = new byte[packetSize]; - } - - public boolean isRunning() { - return running; - } - - public void start() { - running = true; - thread.start(); - } - - public void stop() { - running = false; - thread.interrupt(); - } - - public void run() { - try { - while (running) { - loop(); - } - } catch (Exception e) { - e.printStackTrace(); - } - running = false; - } - - private void loop() { - DatagramPacket packet = receivePacket(); - if (packet.getLength() <= 0) - return; - UDPPacket udpPacket = generatePacket(packet); - if (callback != null) - callback.onReceivedPacket(udpPacket); - else - inbound.add(udpPacket); - notifyPacketReceived(); - } - - private void notifyPacketReceived() { - synchronized (waitingForPacket) { - waitingForPacket.notifyAll(); - } - } - - private DatagramPacket receivePacket() { - DatagramPacket packet = new DatagramPacket(dataBuffer, dataBuffer.length); - try { - socket.receive(packet); - } catch (IOException e) { - if (e.getMessage() != null && (e.getMessage().contains("socket closed") || e.getMessage().contains("Socket closed"))) - running = false; - else - e.printStackTrace(); - packet.setLength(0); - } - return packet; - } - - private UDPPacket generatePacket(DatagramPacket packet) { - byte [] data = new byte[packet.getLength()]; - System.arraycopy(packet.getData(), 0, data, 0, packet.getLength()); - UDPPacket udpPacket = new UDPPacket(packet.getAddress(), packet.getPort(), data); - return udpPacket; - } - - } - -} diff --git a/src/com/projectswg/connection/HolocoreProtocol.java b/src/main/java/com/projectswg/connection/HolocoreProtocol.java similarity index 100% rename from src/com/projectswg/connection/HolocoreProtocol.java rename to src/main/java/com/projectswg/connection/HolocoreProtocol.java diff --git a/src/com/projectswg/connection/HolocoreSocket.java b/src/main/java/com/projectswg/connection/HolocoreSocket.java similarity index 78% rename from src/com/projectswg/connection/HolocoreSocket.java rename to src/main/java/com/projectswg/connection/HolocoreSocket.java index 4733704..8d556b8 100644 --- a/src/com/projectswg/connection/HolocoreSocket.java +++ b/src/main/java/com/projectswg/connection/HolocoreSocket.java @@ -1,29 +1,24 @@ package com.projectswg.connection; -import com.projectswg.common.debug.Log; import com.projectswg.common.network.NetBuffer; -import com.projectswg.common.network.TCPSocket; -import com.projectswg.common.network.TCPSocket.TCPSocketCallback; import com.projectswg.common.network.packets.swg.holo.HoloConnectionStarted; import com.projectswg.common.network.packets.swg.holo.HoloConnectionStopped; import com.projectswg.common.network.packets.swg.holo.HoloSetProtocolVersion; -import com.projectswg.connection.UDPServer.UDPPacket; import com.projectswg.connection.packets.RawPacket; +import me.joshlarson.jlcommon.log.Log; +import me.joshlarson.jlcommon.network.TCPSocket; +import me.joshlarson.jlcommon.network.TCPSocket.TCPSocketCallback; +import me.joshlarson.jlcommon.network.UDPServer; -import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; +import java.net.DatagramPacket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; import java.util.Locale; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; public class HolocoreSocket { @@ -33,6 +28,7 @@ public class HolocoreSocket { private final SWGProtocol swgProtocol; private final AtomicReference status; private final UDPServer udpServer; + private final BlockingQueue udpInboundQueue; private final BlockingQueue inboundQueue; private TCPSocket socket; @@ -42,9 +38,10 @@ public class HolocoreSocket { public HolocoreSocket(InetAddress addr, int port) { this.swgProtocol = new SWGProtocol(); this.status = new AtomicReference<>(ServerConnectionStatus.DISCONNECTED); + this.udpInboundQueue = new LinkedBlockingQueue<>(); + this.inboundQueue = new LinkedBlockingQueue<>(); this.udpServer = createUDPServer(); this.socket = null; - this.inboundQueue = new LinkedBlockingQueue<>(); this.callback = null; this.address = new InetSocketAddress(addr, port); } @@ -129,13 +126,17 @@ public class HolocoreSocket { */ public String getServerStatus(long timeout) { udpServer.send(address, new byte[]{1}); - udpServer.waitForPacket(timeout); - UDPPacket packet = udpServer.receive(); - if (packet == null) - return "OFFLINE"; - NetBuffer data = NetBuffer.wrap(packet.getData()); - data.getByte(); - return data.getAscii(); + try { + DatagramPacket packet = udpInboundQueue.poll(timeout, TimeUnit.MILLISECONDS); + if (packet == null) + return "OFFLINE"; + NetBuffer data = NetBuffer.wrap(packet.getData()); + data.getByte(); + return data.getAscii(); + } catch (InterruptedException e) { + Log.w("Interrupted while waiting for server status response"); + return "UNKNOWN"; + } } /** @@ -150,28 +151,6 @@ public class HolocoreSocket { return finishConnection(socket, timeout); } - /** - * Attempts to connect to the remote server securely. This call is a blocking function that will not - * return until it has either successfully connected or has failed. It starts by initializing a - * TCP connection, then initializes the Holocore connection, then returns. - * @param timeout the timeout for the connect call - * @param keystoreFile the keystore file - * @param password the password for the keystore - * @return TRUE if successful and connected, FALSE on error - * @throws KeyStoreException if KeyManagerFactory.init or TrustManagerFactory.init fails - * @throws NoSuchAlgorithmException if the algorithm for the keystore or key manager could not be found - * @throws CertificateException if any of the certificates in the keystore could not be loaded - * @throws FileNotFoundException if the keystore file does not exist - * @throws IOException if there is an I/O or format problem with the keystore data, if a password is required but not given, or if the given password was incorrect. If the error is due to a wrong password, the cause of the IOException should be an UnrecoverableKeyException - * @throws KeyManagementException if SSLContext.init fails - * @throws UnrecoverableKeyException if the key cannot be recovered (e.g. the given password is wrong). - */ - public boolean connectSecure(int timeout, File keystoreFile, char [] password) throws KeyManagementException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { - TCPSocket socket = new TCPSocket(address, BUFFER_SIZE); -// socket.setupEncryption(keystoreFile, password); - return finishConnection(socket, timeout); - } - private boolean finishConnection(TCPSocket socket, int timeout) { updateStatus(ServerConnectionStatus.CONNECTING, ServerConnectionChangedReason.NONE); try { @@ -233,7 +212,7 @@ public class HolocoreSocket { public boolean send(byte [] raw) { TCPSocket socket = this.socket; if (socket != null) - return socket.send(swgProtocol.assemble(raw)); + return socket.send(swgProtocol.assemble(raw).getBuffer()); return false; } @@ -320,9 +299,11 @@ public class HolocoreSocket { void onConnectionStatusChanged(ServerConnectionStatus oldStatus, ServerConnectionStatus newStatus, ServerConnectionChangedReason reason); } - private static UDPServer createUDPServer() { + private UDPServer createUDPServer() { try { - return new UDPServer(0); + UDPServer server = new UDPServer(new InetSocketAddress(0), 1500, udpInboundQueue::offer); + server.bind(); + return server; } catch (SocketException e) { Log.e(e); } diff --git a/src/com/projectswg/connection/SWGProtocol.java b/src/main/java/com/projectswg/connection/SWGProtocol.java similarity index 100% rename from src/com/projectswg/connection/SWGProtocol.java rename to src/main/java/com/projectswg/connection/SWGProtocol.java diff --git a/src/com/projectswg/connection/ServerConnectionChangedReason.java b/src/main/java/com/projectswg/connection/ServerConnectionChangedReason.java similarity index 100% rename from src/com/projectswg/connection/ServerConnectionChangedReason.java rename to src/main/java/com/projectswg/connection/ServerConnectionChangedReason.java diff --git a/src/com/projectswg/connection/ServerConnectionStatus.java b/src/main/java/com/projectswg/connection/ServerConnectionStatus.java similarity index 100% rename from src/com/projectswg/connection/ServerConnectionStatus.java rename to src/main/java/com/projectswg/connection/ServerConnectionStatus.java diff --git a/src/com/projectswg/connection/packets/RawPacket.java b/src/main/java/com/projectswg/connection/packets/RawPacket.java similarity index 100% rename from src/com/projectswg/connection/packets/RawPacket.java rename to src/main/java/com/projectswg/connection/packets/RawPacket.java