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 2304986..0000000
Binary files a/ClientHolocore.jar and /dev/null differ
diff --git a/PSWGCommon b/PSWGCommon
deleted file mode 160000
index 753adac..0000000
--- a/PSWGCommon
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 753adaca225ec1db30c8b72e35bbe216d8def52e
diff --git a/build.gradle b/build.gradle
index de248dd..b1550e2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,28 +1,19 @@
plugins {
id 'java'
- id 'idea'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
-sourceSets {
- main {
- java {
- srcDir 'src'
- }
- }
-}
-
-jar {
- from sourceSets.main.allSource
- archiveName = "PSWGCommon.jar"
-}
-
-task wrapper(type: Wrapper) {
- gradleVersion = "4.4"
+repositories {
+ jcenter()
}
dependencies {
- compile project(':PSWGCommon')
+ compile project(':pswgcommon')
+ testCompile 'junit:junit:4.12'
+}
+
+task wrapper(type: Wrapper) {
+ gradleVersion = "4.7"
}
diff --git a/settings.gradle b/settings.gradle
index 40825e9..2e860fa 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':PSWGCommon'
+include ':pswgcommon'
diff --git a/src/com/projectswg/connection/UDPServer.java b/src/com/projectswg/connection/UDPServer.java
deleted file mode 100644
index 2ec06d9..0000000
--- a/src/com/projectswg/connection/UDPServer.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/***********************************************************************************
-* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
-* *
-* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
-* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
-* Our goal is to create an emulator which will provide a server for players to *
-* continue playing a game similar to the one they used to play. We are basing *
-* it on the final publish of the game prior to end-game events. *
-* *
-* This file is part of Holocore. *
-* *
-* -------------------------------------------------------------------------------- *
-* *
-* Holocore is free software: you can redistribute it and/or modify *
-* it under the terms of the GNU Affero General Public License as *
-* published by the Free Software Foundation, either version 3 of the *
-* License, or (at your option) any later version. *
-* *
-* Holocore is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU Affero General Public License for more details. *
-* *
-* You should have received a copy of the GNU Affero General Public License *
-* along with Holocore. If not, see . *
-* *
-***********************************************************************************/
-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