diff --git a/.classpath b/.classpath
index 87e8f73..d91019d 100644
--- a/.classpath
+++ b/.classpath
@@ -2,32 +2,11 @@
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/.project b/.project
index f6121aa..74f4947 100644
--- a/.project
+++ b/.project
@@ -6,18 +6,18 @@
- org.eclipse.xtext.ui.shared.xtextBuilder
+ org.eclipse.jdt.core.javabuilder
- org.eclipse.jdt.core.javabuilder
+ org.eclipse.buildship.core.gradleprojectbuilder
org.eclipse.jdt.core.javanature
- org.eclipse.xtext.ui.shared.xtextNature
+ org.eclipse.buildship.core.gradleprojectnature
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 673e5a3..0000000
--- a/build.xml
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
- Standard Lightspeed Build File
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build_frontend.gradle b/build_frontend.gradle
new file mode 100644
index 0000000..a357512
--- /dev/null
+++ b/build_frontend.gradle
@@ -0,0 +1,64 @@
+apply plugin: 'application'
+apply plugin: 'com.github.johnrengelman.shadow'
+apply plugin: 'java'
+
+mainClassName = 'com.projectswg.lightspeed_frontend.LightspeedFrontendGUI'
+
+manifest {
+ attributes 'Main-Class': 'com.projectswg.lightspeed_frontend.LightspeedFrontendGUI'
+}
+
+sourceSets {
+ main {
+ java {
+ srcDirs = ['src']
+ includes ['**/*.java']
+ }
+ resources {
+ srcDirs = ['src']
+ includes = ['**/*.fxml', '**/*.css', '**/*.properties']
+ }
+ }
+ test {
+ java {
+ srcDirs = ['test']
+ }
+ }
+}
+
+test {
+ testLogging {
+ events "skipped", "failed"
+ }
+ afterSuite { TestDescriptor td, TestResult tr ->
+ println 'Tests run: ('+tr.getTestCount()+'), Failures: ('+tr.getFailedTestCount()+'), Errors: (0)'
+ }
+ include 'com/projectswg/lightspeed/TestLightspeed.class'
+}
+
+shadowJar{
+ archiveName = "LightspeedFrontend.${extension}"
+}
+
+dependencies {
+ compileOnly fileTree(dir: 'lib', include: ['*.jar'])
+ runtime fileTree(dir: 'lib_frontend', include: ['*.jar'])
+}
+
+repositories {
+ maven { url 'https://repo.gradle.org/gradle/libs-releases' }
+ jcenter()
+}
+
+dependencies {
+ compile "org.gradle:gradle-tooling-api:3.3"
+}
+
+buildscript {
+ repositories {
+ maven { url 'https://plugins.gradle.org/m2/' }
+ }
+ dependencies {
+ classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.0'
+ }
+}
diff --git a/build_server.gradle b/build_server.gradle
new file mode 100644
index 0000000..93bcbd2
--- /dev/null
+++ b/build_server.gradle
@@ -0,0 +1,56 @@
+apply plugin: 'application'
+apply plugin: 'com.github.johnrengelman.shadow'
+apply plugin: 'java'
+
+mainClassName = 'com.projectswg.Lightspeed'
+
+manifest {
+ attributes 'Main-Class': 'com.projectswg.Lightspeed'
+}
+
+sourceSets {
+ main {
+ java {
+ srcDirs = ['src']
+ }
+ }
+ test {
+ java {
+ srcDirs = ['test']
+ }
+ }
+}
+
+test {
+ testLogging {
+ events "skipped", "failed"
+ }
+ afterSuite { TestDescriptor td, TestResult tr ->
+ println 'Tests run: ('+tr.getTestCount()+'), Failures: ('+tr.getFailedTestCount()+'), Errors: (0)'
+ }
+ include 'com/projectswg/lightspeed/TestLightspeed.class'
+}
+
+shadowJar{
+ archiveName = "Lightspeed.${extension}"
+}
+
+dependencies {
+ compile fileTree(dir: 'lib', include: ['*.jar'])
+}
+
+repositories {
+ maven { url 'https://repo.gradle.org/gradle/libs-releases' }
+ jcenter()
+}
+
+dependencies {
+ compile "org.gradle:gradle-tooling-api:3.3"
+}
+
+buildscript {
+ repositories {
+ maven { url 'https://plugins.gradle.org/m2/' }
+ }
+ dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.0' }
+}
diff --git a/lib/PSWGCommon.jar b/lib/PSWGCommon.jar
index 2b18b1b..54077f6 100644
Binary files a/lib/PSWGCommon.jar and b/lib/PSWGCommon.jar differ
diff --git a/src/com/projectswg/Lightspeed.java b/src/com/projectswg/Lightspeed.java
index 4a5858b..85dcbbb 100644
--- a/src/com/projectswg/Lightspeed.java
+++ b/src/com/projectswg/Lightspeed.java
@@ -30,6 +30,7 @@ package com.projectswg;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import com.projectswg.common.data.info.RelationalServerFactory;
import com.projectswg.common.debug.Log;
import com.projectswg.common.debug.Log.LogLevel;
import com.projectswg.common.debug.log_wrapper.ConsoleLogWrapper;
@@ -45,6 +46,7 @@ public class Lightspeed {
if (MAIN_THREAD.get() != null)
throw new IllegalStateException("Cannot run main() twice!");
Log.addWrapper(new ConsoleLogWrapper(LogLevel.VERBOSE));
+ RelationalServerFactory.setBasePath("data/");
MAIN_THREAD.set(Thread.currentThread());
LightspeedMainManager.setDataManager(new HeavyweightDataManager());
LightspeedMainManager.getDataManager().initialize();
diff --git a/src/com/projectswg/LightweightLightspeed.java b/src/com/projectswg/LightweightLightspeed.java
index 7afdeb1..8a9215c 100644
--- a/src/com/projectswg/LightweightLightspeed.java
+++ b/src/com/projectswg/LightweightLightspeed.java
@@ -29,8 +29,8 @@ package com.projectswg;
import java.util.concurrent.atomic.AtomicBoolean;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.Config;
import com.projectswg.common.info.ConfigFile;
import com.projectswg.common.info.LightweightDataManager;
import com.projectswg.lightspeed.LightspeedMainManager;
diff --git a/src/com/projectswg/common/control/LightspeedManager.java b/src/com/projectswg/common/control/LightspeedManager.java
index 42bacd4..2d3b43f 100644
--- a/src/com/projectswg/common/control/LightspeedManager.java
+++ b/src/com/projectswg/common/control/LightspeedManager.java
@@ -28,7 +28,7 @@
package com.projectswg.common.control;
import com.projectswg.common.data.BackendData;
-import com.projectswg.common.info.Config;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.info.ConfigFile;
import com.projectswg.common.info.DataManager;
diff --git a/src/com/projectswg/common/control/LightspeedService.java b/src/com/projectswg/common/control/LightspeedService.java
index bbf30bb..dc79cc1 100644
--- a/src/com/projectswg/common/control/LightspeedService.java
+++ b/src/com/projectswg/common/control/LightspeedService.java
@@ -28,7 +28,7 @@
package com.projectswg.common.control;
import com.projectswg.common.data.BackendData;
-import com.projectswg.common.info.Config;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.info.ConfigFile;
import com.projectswg.common.info.DataManager;
diff --git a/src/com/projectswg/common/data/BuildHistoryTable.java b/src/com/projectswg/common/data/BuildHistoryTable.java
index 5df9cd7..594da14 100644
--- a/src/com/projectswg/common/data/BuildHistoryTable.java
+++ b/src/com/projectswg/common/data/BuildHistoryTable.java
@@ -34,9 +34,9 @@ import java.util.ArrayList;
import java.util.List;
import com.projectswg.common.data.SQLBuildData.BuildInformationBuilder;
+import com.projectswg.common.data.info.RelationalDatabase;
+import com.projectswg.common.data.info.RelationalServerFactory;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.RelationalDatabase;
-import com.projectswg.common.info.RelationalServerFactory;
import com.projectswg.lightspeed_frontend.data.SharedBuildData.BuildState;
class BuildHistoryTable implements AutoCloseable {
@@ -66,6 +66,7 @@ class BuildHistoryTable implements AutoCloseable {
this.getBuildByIdStatement = db.prepareStatement(GET_BUILD_BY_ID_SQL);
}
+ @Override
public void close() {
if (database != null)
database.close();
diff --git a/src/com/projectswg/common/data/DeploymentTable.java b/src/com/projectswg/common/data/DeploymentTable.java
index 650573b..0d07c1b 100644
--- a/src/com/projectswg/common/data/DeploymentTable.java
+++ b/src/com/projectswg/common/data/DeploymentTable.java
@@ -34,9 +34,9 @@ import java.util.ArrayList;
import java.util.List;
import com.projectswg.common.data.SQLDeploymentData.DeploymentInformationBuilder;
+import com.projectswg.common.data.info.RelationalDatabase;
+import com.projectswg.common.data.info.RelationalServerFactory;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.RelationalDatabase;
-import com.projectswg.common.info.RelationalServerFactory;
class DeploymentTable implements AutoCloseable {
@@ -54,6 +54,7 @@ class DeploymentTable implements AutoCloseable {
private final PreparedStatement getDeploymentsByServerStatement;
private final PreparedStatement getLastDeploymentStatement;
+
public DeploymentTable() {
this.database = RelationalServerFactory.getServerDatabase("lightspeed.db");
this.insertDeploymentStatement = database.prepareStatement(INSERT_DEPLOYMENT_SQL);
@@ -72,6 +73,7 @@ class DeploymentTable implements AutoCloseable {
this.getLastDeploymentStatement = db.prepareStatement(GET_LAST_DEPLOYMENT_SQL);
}
+ @Override
public void close() {
if (database != null)
database.close();
diff --git a/src/com/projectswg/common/data/HeavyweightBackendData.java b/src/com/projectswg/common/data/HeavyweightBackendData.java
index 0ced3ce..d28d805 100644
--- a/src/com/projectswg/common/data/HeavyweightBackendData.java
+++ b/src/com/projectswg/common/data/HeavyweightBackendData.java
@@ -32,8 +32,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import com.projectswg.common.info.RelationalDatabase;
-import com.projectswg.common.info.RelationalServerFactory;
+import com.projectswg.common.data.info.RelationalDatabase;
+import com.projectswg.common.data.info.RelationalServerFactory;
import com.projectswg.lightspeed.build.ServerBuildData;
import com.projectswg.lightspeed.deployment.ServerDeploymentData;
import com.projectswg.lightspeed.server.ServerServerData;
@@ -48,18 +48,21 @@ public class HeavyweightBackendData implements BackendData {
loadServers();
}
+ @Override
public void insertBuild(ServerBuildData build) {
try (BuildHistoryTable buildTable = new BuildHistoryTable()) {
buildTable.insertBuildHistory(new SQLBuildData(build));
}
}
+ @Override
public void insertDeployment(ServerDeploymentData deployment) {
try (DeploymentTable deploymentTable = new DeploymentTable()) {
deploymentTable.insertDeployment(new SQLDeploymentData(deployment));
}
}
+ @Override
public List getServerList() {
List servers;
synchronized (serverMap) {
@@ -68,6 +71,7 @@ public class HeavyweightBackendData implements BackendData {
return servers;
}
+ @Override
public ServerServerData getServer(String serverId) {
synchronized (serverMap) {
ServerServerData server = serverMap.get(serverId);
diff --git a/src/com/projectswg/common/info/DataManager.java b/src/com/projectswg/common/info/DataManager.java
index 1a38d58..807cd06 100644
--- a/src/com/projectswg/common/info/DataManager.java
+++ b/src/com/projectswg/common/info/DataManager.java
@@ -28,6 +28,7 @@
package com.projectswg.common.info;
import com.projectswg.common.data.BackendData;
+import com.projectswg.common.data.info.Config;
public interface DataManager {
diff --git a/src/com/projectswg/common/info/HeavyweightDataManager.java b/src/com/projectswg/common/info/HeavyweightDataManager.java
index 63a843f..336514d 100644
--- a/src/com/projectswg/common/info/HeavyweightDataManager.java
+++ b/src/com/projectswg/common/info/HeavyweightDataManager.java
@@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import com.projectswg.common.data.BackendData;
import com.projectswg.common.data.HeavyweightBackendData;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.debug.Log;
import com.projectswg.common.debug.log_wrapper.FileLogWrapper;
@@ -49,6 +50,7 @@ public class HeavyweightDataManager implements DataManager {
initialized = new AtomicBoolean(false);
}
+ @Override
public synchronized void initialize() {
if (initialized.getAndSet(true))
return;
@@ -62,6 +64,7 @@ public class HeavyweightDataManager implements DataManager {
}
}
+ @Override
public synchronized void terminate() {
if (!initialized.getAndSet(false))
return;
diff --git a/src/com/projectswg/common/info/LightweightConfig.java b/src/com/projectswg/common/info/LightweightConfig.java
index ee62fdb..95fa183 100644
--- a/src/com/projectswg/common/info/LightweightConfig.java
+++ b/src/com/projectswg/common/info/LightweightConfig.java
@@ -30,6 +30,8 @@ package com.projectswg.common.info;
import java.io.File;
import java.util.Map;
+import com.projectswg.common.data.info.Config;
+
public class LightweightConfig extends Config {
public LightweightConfig(String filename) {
@@ -44,10 +46,12 @@ public class LightweightConfig extends Config {
super(file);
}
+ @Override
public Map load() {
return null;
}
+ @Override
public boolean save() {
return true;
}
diff --git a/src/com/projectswg/common/info/LightweightDataManager.java b/src/com/projectswg/common/info/LightweightDataManager.java
index d612ff3..6ad52f5 100644
--- a/src/com/projectswg/common/info/LightweightDataManager.java
+++ b/src/com/projectswg/common/info/LightweightDataManager.java
@@ -32,6 +32,7 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import com.projectswg.common.data.LightweightBackendData;
+import com.projectswg.common.data.info.Config;
public class LightweightDataManager implements DataManager {
@@ -45,12 +46,14 @@ public class LightweightDataManager implements DataManager {
configs = new HashMap<>();
}
+ @Override
public synchronized void initialize() {
if (initialized.getAndSet(true))
return;
setupConfigs();
}
+ @Override
public synchronized void terminate() {
if (!initialized.getAndSet(false))
return;
diff --git a/src/com/projectswg/common/network/packets/Packet.java b/src/com/projectswg/common/network/packets/Packet.java
index 2a05b59..08a27e8 100644
--- a/src/com/projectswg/common/network/packets/Packet.java
+++ b/src/com/projectswg/common/network/packets/Packet.java
@@ -29,9 +29,23 @@ package com.projectswg.common.network.packets;
import com.projectswg.common.debug.Log;
import com.projectswg.common.network.packets.connection.ConnectionProbePacket;
-import com.projectswg.common.network.packets.post.*;
-import com.projectswg.common.network.packets.request.*;
-import com.projectswg.common.network.packets.response.*;
+import com.projectswg.common.network.packets.post.PostBuildPacket;
+import com.projectswg.common.network.packets.post.PostDeployPacket;
+import com.projectswg.common.network.packets.post.PostResult;
+import com.projectswg.common.network.packets.post.PostStopBuildPacket;
+import com.projectswg.common.network.packets.post.PostStopDeployPacket;
+import com.projectswg.common.network.packets.request.RequestBuildDetailedPacket;
+import com.projectswg.common.network.packets.request.RequestBuildListPacket;
+import com.projectswg.common.network.packets.request.RequestDeploymentDetailedPacket;
+import com.projectswg.common.network.packets.request.RequestDeploymentListPacket;
+import com.projectswg.common.network.packets.request.RequestServerDetailedPacket;
+import com.projectswg.common.network.packets.request.RequestServerListPacket;
+import com.projectswg.common.network.packets.response.ResponseBuildDetailedPacket;
+import com.projectswg.common.network.packets.response.ResponseBuildListPacket;
+import com.projectswg.common.network.packets.response.ResponseDeploymentDetailedPacket;
+import com.projectswg.common.network.packets.response.ResponseDeploymentListPacket;
+import com.projectswg.common.network.packets.response.ResponseServerDetailedPacket;
+import com.projectswg.common.network.packets.response.ResponseServerListPacket;
import me.joshlarson.json.JSONObject;
diff --git a/src/com/projectswg/common/network/packets/connection/ConnectionPacket.java b/src/com/projectswg/common/network/packets/connection/ConnectionPacket.java
index 2c13aa0..3a9a9d5 100644
--- a/src/com/projectswg/common/network/packets/connection/ConnectionPacket.java
+++ b/src/com/projectswg/common/network/packets/connection/ConnectionPacket.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package com.projectswg.common.network.packets.connection;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public abstract class ConnectionPacket extends Packet {
public ConnectionPacket(JSONObject json, PacketType type) {
diff --git a/src/com/projectswg/common/network/packets/connection/ConnectionProbePacket.java b/src/com/projectswg/common/network/packets/connection/ConnectionProbePacket.java
index 1050bd0..b85926d 100644
--- a/src/com/projectswg/common/network/packets/connection/ConnectionProbePacket.java
+++ b/src/com/projectswg/common/network/packets/connection/ConnectionProbePacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.connection;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class ConnectionProbePacket extends ConnectionPacket {
public ConnectionProbePacket(JSONObject json) {
diff --git a/src/com/projectswg/common/network/packets/post/PostBuildPacket.java b/src/com/projectswg/common/network/packets/post/PostBuildPacket.java
index 537fb31..4b49332 100644
--- a/src/com/projectswg/common/network/packets/post/PostBuildPacket.java
+++ b/src/com/projectswg/common/network/packets/post/PostBuildPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.post;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class PostBuildPacket extends PostPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/post/PostDeployPacket.java b/src/com/projectswg/common/network/packets/post/PostDeployPacket.java
index c2023d9..d1dd8bc 100644
--- a/src/com/projectswg/common/network/packets/post/PostDeployPacket.java
+++ b/src/com/projectswg/common/network/packets/post/PostDeployPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.post;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class PostDeployPacket extends PostPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/post/PostPacket.java b/src/com/projectswg/common/network/packets/post/PostPacket.java
index 5678cc9..413710c 100644
--- a/src/com/projectswg/common/network/packets/post/PostPacket.java
+++ b/src/com/projectswg/common/network/packets/post/PostPacket.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package com.projectswg.common.network.packets.post;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public abstract class PostPacket extends Packet {
public PostPacket(JSONObject json, PacketType type) {
diff --git a/src/com/projectswg/common/network/packets/post/PostResult.java b/src/com/projectswg/common/network/packets/post/PostResult.java
index b2f2fb3..602e9c4 100644
--- a/src/com/projectswg/common/network/packets/post/PostResult.java
+++ b/src/com/projectswg/common/network/packets/post/PostResult.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package com.projectswg.common.network.packets.post;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class PostResult extends Packet {
private static final String SUCCESS = "success";
diff --git a/src/com/projectswg/common/network/packets/post/PostStopBuildPacket.java b/src/com/projectswg/common/network/packets/post/PostStopBuildPacket.java
index 7e76899..1db03d8 100644
--- a/src/com/projectswg/common/network/packets/post/PostStopBuildPacket.java
+++ b/src/com/projectswg/common/network/packets/post/PostStopBuildPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.post;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class PostStopBuildPacket extends PostPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/post/PostStopDeployPacket.java b/src/com/projectswg/common/network/packets/post/PostStopDeployPacket.java
index fae14d2..b769628 100644
--- a/src/com/projectswg/common/network/packets/post/PostStopDeployPacket.java
+++ b/src/com/projectswg/common/network/packets/post/PostStopDeployPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.post;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class PostStopDeployPacket extends PostPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/request/RequestBuildDetailedPacket.java b/src/com/projectswg/common/network/packets/request/RequestBuildDetailedPacket.java
index d05cdaa..ff8523a 100644
--- a/src/com/projectswg/common/network/packets/request/RequestBuildDetailedPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestBuildDetailedPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class RequestBuildDetailedPacket extends RequestPacket {
private static final String BUILD_ID = "build_id";
diff --git a/src/com/projectswg/common/network/packets/request/RequestBuildListPacket.java b/src/com/projectswg/common/network/packets/request/RequestBuildListPacket.java
index 69a0eea..c18bd00 100644
--- a/src/com/projectswg/common/network/packets/request/RequestBuildListPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestBuildListPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class RequestBuildListPacket extends RequestPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/request/RequestDeploymentDetailedPacket.java b/src/com/projectswg/common/network/packets/request/RequestDeploymentDetailedPacket.java
index 70ef45b..e6a505c 100644
--- a/src/com/projectswg/common/network/packets/request/RequestDeploymentDetailedPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestDeploymentDetailedPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class RequestDeploymentDetailedPacket extends RequestPacket {
private static final String DEPLOYMENT_ID = "deployment_id";
diff --git a/src/com/projectswg/common/network/packets/request/RequestDeploymentListPacket.java b/src/com/projectswg/common/network/packets/request/RequestDeploymentListPacket.java
index 938dca9..7cf86b6 100644
--- a/src/com/projectswg/common/network/packets/request/RequestDeploymentListPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestDeploymentListPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class RequestDeploymentListPacket extends RequestPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/request/RequestPacket.java b/src/com/projectswg/common/network/packets/request/RequestPacket.java
index 23ece2a..8a0645d 100644
--- a/src/com/projectswg/common/network/packets/request/RequestPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestPacket.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public abstract class RequestPacket extends Packet {
public RequestPacket(JSONObject json, PacketType type) {
diff --git a/src/com/projectswg/common/network/packets/request/RequestServerDetailedPacket.java b/src/com/projectswg/common/network/packets/request/RequestServerDetailedPacket.java
index fc6ea37..6417b38 100644
--- a/src/com/projectswg/common/network/packets/request/RequestServerDetailedPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestServerDetailedPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class RequestServerDetailedPacket extends RequestPacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/request/RequestServerListPacket.java b/src/com/projectswg/common/network/packets/request/RequestServerListPacket.java
index ad4315c..0eecbd2 100644
--- a/src/com/projectswg/common/network/packets/request/RequestServerListPacket.java
+++ b/src/com/projectswg/common/network/packets/request/RequestServerListPacket.java
@@ -27,10 +27,10 @@
***********************************************************************************/
package com.projectswg.common.network.packets.request;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public class RequestServerListPacket extends RequestPacket {
public RequestServerListPacket(JSONObject json) {
diff --git a/src/com/projectswg/common/network/packets/response/ResponseBuildDetailedPacket.java b/src/com/projectswg/common/network/packets/response/ResponseBuildDetailedPacket.java
index 7fe9ae6..622e502 100644
--- a/src/com/projectswg/common/network/packets/response/ResponseBuildDetailedPacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponseBuildDetailedPacket.java
@@ -27,14 +27,14 @@
***********************************************************************************/
package com.projectswg.common.network.packets.response;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.data.TestDetails;
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
import com.projectswg.lightspeed_frontend.data.SharedBuildData.BuildState;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import me.joshlarson.json.JSONObject;
+
public class ResponseBuildDetailedPacket extends ResponsePacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/response/ResponseBuildListPacket.java b/src/com/projectswg/common/network/packets/response/ResponseBuildListPacket.java
index 4986cd4..f03eb10 100644
--- a/src/com/projectswg/common/network/packets/response/ResponseBuildListPacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponseBuildListPacket.java
@@ -30,13 +30,13 @@ package com.projectswg.common.network.packets.response;
import java.util.ArrayList;
import java.util.List;
-import me.joshlarson.json.JSONArray;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import me.joshlarson.json.JSONArray;
+import me.joshlarson.json.JSONObject;
+
public class ResponseBuildListPacket extends ResponsePacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/response/ResponseDeploymentDetailedPacket.java b/src/com/projectswg/common/network/packets/response/ResponseDeploymentDetailedPacket.java
index 675e334..bbf46f9 100644
--- a/src/com/projectswg/common/network/packets/response/ResponseDeploymentDetailedPacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponseDeploymentDetailedPacket.java
@@ -27,13 +27,13 @@
***********************************************************************************/
package com.projectswg.common.network.packets.response;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
-import com.projectswg.lightspeed_frontend.data.SharedServerData;
import com.projectswg.lightspeed_frontend.data.SharedDeploymentData.DeploymentState;
+import com.projectswg.lightspeed_frontend.data.SharedServerData;
+
+import me.joshlarson.json.JSONObject;
public class ResponseDeploymentDetailedPacket extends ResponsePacket {
diff --git a/src/com/projectswg/common/network/packets/response/ResponseDeploymentListPacket.java b/src/com/projectswg/common/network/packets/response/ResponseDeploymentListPacket.java
index e23c18f..d805ca8 100644
--- a/src/com/projectswg/common/network/packets/response/ResponseDeploymentListPacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponseDeploymentListPacket.java
@@ -30,14 +30,14 @@ package com.projectswg.common.network.packets.response;
import java.util.ArrayList;
import java.util.List;
-import me.joshlarson.json.JSONArray;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import me.joshlarson.json.JSONArray;
+import me.joshlarson.json.JSONObject;
+
public class ResponseDeploymentListPacket extends ResponsePacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/response/ResponsePacket.java b/src/com/projectswg/common/network/packets/response/ResponsePacket.java
index 38e7b9c..e6f3b8a 100644
--- a/src/com/projectswg/common/network/packets/response/ResponsePacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponsePacket.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package com.projectswg.common.network.packets.response;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.PacketType;
+import me.joshlarson.json.JSONObject;
+
public abstract class ResponsePacket extends Packet {
public ResponsePacket(JSONObject json, PacketType type) {
diff --git a/src/com/projectswg/common/network/packets/response/ResponseServerDetailedPacket.java b/src/com/projectswg/common/network/packets/response/ResponseServerDetailedPacket.java
index c7582b5..a5bde5c 100644
--- a/src/com/projectswg/common/network/packets/response/ResponseServerDetailedPacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponseServerDetailedPacket.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package com.projectswg.common.network.packets.response;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import me.joshlarson.json.JSONObject;
+
public class ResponseServerDetailedPacket extends ResponsePacket {
private static final String SERVER_ID = "server_id";
diff --git a/src/com/projectswg/common/network/packets/response/ResponseServerListPacket.java b/src/com/projectswg/common/network/packets/response/ResponseServerListPacket.java
index 767923c..4690ff0 100644
--- a/src/com/projectswg/common/network/packets/response/ResponseServerListPacket.java
+++ b/src/com/projectswg/common/network/packets/response/ResponseServerListPacket.java
@@ -30,12 +30,12 @@ package com.projectswg.common.network.packets.response;
import java.util.ArrayList;
import java.util.List;
-import me.joshlarson.json.JSONArray;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import me.joshlarson.json.JSONArray;
+import me.joshlarson.json.JSONObject;
+
public class ResponseServerListPacket extends ResponsePacket {
private static final String SERVER_LIST = "server_list";
diff --git a/src/com/projectswg/lightspeed/CommunicationService.java b/src/com/projectswg/lightspeed/CommunicationService.java
index ec16a77..e3ca03e 100644
--- a/src/com/projectswg/lightspeed/CommunicationService.java
+++ b/src/com/projectswg/lightspeed/CommunicationService.java
@@ -56,22 +56,22 @@ import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.response.Status;
import org.nanohttpd.protocols.http.threading.IAsyncRunner;
-import resources.common.BCrypt;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.concurrency.PswgBasicScheduledThread;
import com.projectswg.common.concurrency.PswgThreadPool;
import com.projectswg.common.control.LightspeedService;
import com.projectswg.common.data.CsvTable;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.debug.Assert;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.Config;
import com.projectswg.common.info.ConfigFile;
import com.projectswg.common.intents.RegisterHttpListenerIntent;
import com.projectswg.common.network.packets.PacketType;
import com.projectswg.common.network.packets.connection.ConnectionProbePacket;
import com.projectswg.lightspeed.communication.HttpResponder;
+import me.joshlarson.json.JSONObject;
+import resources.common.BCrypt;
+
public class CommunicationService extends LightspeedService {
private final NanoHTTPD httpServer;
@@ -84,6 +84,7 @@ public class CommunicationService extends LightspeedService {
public CommunicationService() {
this.httpServer = new NanoHTTPD(44444) {
+ @Override
public Response serve(IHTTPSession session) {
return CommunicationService.this.serve(session);
}
diff --git a/src/com/projectswg/lightspeed/DeploymentService.java b/src/com/projectswg/lightspeed/DeploymentService.java
index 34633dd..a582fb0 100644
--- a/src/com/projectswg/lightspeed/DeploymentService.java
+++ b/src/com/projectswg/lightspeed/DeploymentService.java
@@ -30,6 +30,7 @@ package com.projectswg.lightspeed;
import java.io.File;
import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -38,13 +39,10 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
-import me.joshlarson.json.JSONObject;
-import network.packets.swg.admin.AdminShutdownServer;
-
import com.projectswg.common.control.LightspeedService;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.debug.Assert;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.Config;
import com.projectswg.common.info.ConfigFile;
import com.projectswg.common.intents.LaunchStarshipIntent;
import com.projectswg.common.intents.RegisterHttpListenerIntent;
@@ -63,10 +61,13 @@ import com.projectswg.lightspeed.build.ServerBuildData;
import com.projectswg.lightspeed.deployment.ServerDeploymentData;
import com.projectswg.lightspeed.sequenced.SequencedStarter;
import com.projectswg.lightspeed.server.ServerServerData;
-import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
import com.projectswg.lightspeed_frontend.data.SharedBuildData.BuildState;
+import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
import com.projectswg.lightspeed_frontend.data.SharedDeploymentData.DeploymentState;
+import me.joshlarson.json.JSONObject;
+import network.packets.swg.admin.AdminShutdownServer;
+
public class DeploymentService extends LightspeedService {
private final AtomicLong deploymentId;
@@ -305,14 +306,46 @@ public class DeploymentService extends LightspeedService {
File jar = new File("data"+File.separatorChar+"releases"+File.separatorChar+deployment.getServer().getName()+".jar");
File dir = new File(deployment.getServer().getDirectory());
String [] jvmArguments = deployment.getServer().getJvmArguments().split(" ");
- String [] command = new String[3 + jvmArguments.length];
- command[0] = java.getAbsolutePath();
- System.arraycopy(jvmArguments, 0, command, 1, jvmArguments.length);
- command[jvmArguments.length+1] = "-jar";
- command[jvmArguments.length+2] = jar.getAbsolutePath();
+ String [] command = createStringArray(java.getAbsolutePath(), jvmArguments, "-jar", jar);
+ Log.d("Command: %s", Arrays.toString(command));
return StarshipProcess.create(dir, command);
}
+ private String [] createStringArray(Object ... objects) {
+ int size = 0;
+ for (Object o : objects) {
+ if (o instanceof String) {
+ if (!((String) o).isEmpty())
+ size++;
+ } else if (o instanceof String[]) {
+ for (String str : (String[]) o) {
+ if (!str.isEmpty())
+ size++;
+ }
+ } else if (o instanceof File) {
+ size++;
+ } else {
+ throw new IllegalArgumentException("Invalid argument: " + o);
+ }
+ }
+ String [] ret = new String[size];
+ int index = 0;
+ for (Object o : objects) {
+ if (o instanceof String) {
+ if (!((String) o).isEmpty())
+ ret[index++] = (String) o;
+ } else if (o instanceof File) {
+ ret[index++] = ((File) o).getAbsolutePath();
+ } else if (o instanceof String[]) {
+ for (String str : (String[]) o) {
+ if (!str.isEmpty())
+ ret[index++] = str;
+ }
+ }
+ }
+ return ret;
+ }
+
private void onDeploymentStarted(ServerDeploymentData deployment) {
deployment.setStartTime(TimeUtilities.getTime());
deployment.setDeploymentState(DeploymentState.RUNNING);
diff --git a/src/com/projectswg/lightspeed/StarshipProcess.java b/src/com/projectswg/lightspeed/StarshipProcess.java
index 6d342bb..dcebaa8 100644
--- a/src/com/projectswg/lightspeed/StarshipProcess.java
+++ b/src/com/projectswg/lightspeed/StarshipProcess.java
@@ -30,7 +30,9 @@ package com.projectswg.lightspeed;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import com.projectswg.common.debug.Assert;
@@ -116,6 +118,17 @@ public class StarshipProcess {
}
public void gobbleOutput(ServerDeploymentData deployment) {
+ try (InputStream is = process.getInputStream()) {
+ byte [] buffer = new byte[256];
+ int bytes;
+ SharedDeploymentData sharedDeployment = deployment.getShared();
+ while ((bytes = is.read(buffer)) >= 0) {
+ sharedDeployment.appendOutput(new String(buffer, 0, bytes, StandardCharsets.UTF_8)); // gobble.
+ }
+ } catch (IOException e) {
+ if (Assert.debug() && (e.getMessage() == null || !e.getMessage().toLowerCase().contains("closed")))
+ Log.e(e);
+ }
try (BufferedReader gobbler = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
SharedDeploymentData sharedDeployment = deployment.getShared();
diff --git a/src/com/projectswg/lightspeed/build/BuildService.java b/src/com/projectswg/lightspeed/build/BuildService.java
index 28f033c..eea1fab 100644
--- a/src/com/projectswg/lightspeed/build/BuildService.java
+++ b/src/com/projectswg/lightspeed/build/BuildService.java
@@ -39,11 +39,9 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.control.LightspeedService;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.Config;
import com.projectswg.common.info.ConfigFile;
import com.projectswg.common.intents.LaunchStarshipIntent;
import com.projectswg.common.intents.PrepareStarshipIntent;
@@ -62,6 +60,8 @@ import com.projectswg.lightspeed.server.ServerServerData;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
import com.projectswg.lightspeed_frontend.data.SharedBuildData.BuildState;
+import me.joshlarson.json.JSONObject;
+
public class BuildService extends LightspeedService {
private final AtomicLong buildId;
@@ -206,6 +206,7 @@ public class BuildService extends LightspeedService {
}
}
+ @Override
public void onCancelled(ServerBuildData build) {
removeInProgress();
Log.i("Build cancelled: %s", serverId);
diff --git a/src/com/projectswg/lightspeed/build/JavaBuildMethod.java b/src/com/projectswg/lightspeed/build/JavaBuildMethod.java
index 4f04ba9..a04c63c 100644
--- a/src/com/projectswg/lightspeed/build/JavaBuildMethod.java
+++ b/src/com/projectswg/lightspeed/build/JavaBuildMethod.java
@@ -27,31 +27,34 @@
***********************************************************************************/
package com.projectswg.lightspeed.build;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.gradle.tooling.GradleConnector;
+import org.gradle.tooling.ProjectConnection;
+
import com.projectswg.common.data.TestDetails;
import com.projectswg.common.debug.Log;
import com.projectswg.common.utilities.TimeUtilities;
import com.projectswg.lightspeed.build.ServerBuildData.InstallationCallback;
-import com.projectswg.lightspeed.build.java_builder.RepoInstaller;
import com.projectswg.lightspeed.server.ServerServerData;
import com.projectswg.lightspeed_frontend.data.SharedBuildData.BuildState;
public class JavaBuildMethod {
- private static final Pattern JUNIT_PATTERN = Pattern.compile("Tests run: (\\d+), Failures: (\\d+), Errors: (\\d+).*$");
- private static final String SEP = File.separator;
+ private static final Pattern JUNIT_PATTERN = Pattern.compile(".*Tests run: \\((\\d+)\\), Failures: \\((\\d+)\\).*", Pattern.DOTALL);
- private final RepoInstaller installer;
private final ServerBuildData buildData;
private final InstallationCallback callback;
+ private final ProjectConnection connection;
public JavaBuildMethod(File jdk, ServerServerData serverData, ServerBuildData buildData, InstallationCallback callback) {
- this.installer = new RepoInstaller(processRepositoryArgument(serverData.getDirectory()), jdk);
this.buildData = buildData;
this.callback = callback;
+ this.connection = GradleConnector.newConnector().forProjectDirectory(new File(serverData.getDirectory())).connect();
}
public void start() {
@@ -60,12 +63,6 @@ public class JavaBuildMethod {
}, "java-build-"+buildData.getId()).start();
}
- private File processRepositoryArgument(String repo) {
- if (repo.endsWith(SEP))
- return new File(repo.substring(0, repo.length()-1));
- return new File(repo);
- }
-
private void createJar() {
try {
buildData.setTime(TimeUtilities.getTime());
@@ -85,8 +82,13 @@ public class JavaBuildMethod {
private boolean build() {
updateState(BuildState.COMPILING);
long start = System.nanoTime();
- StringBuilder output = new StringBuilder("");
- boolean success = installer.executeAnt("compile", output);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ boolean success = true;
+ try {
+ connection.newBuild().forTasks("compileJava").setStandardOutput(output).setStandardError(output).run();
+ } catch (Exception e) {
+ success = false;
+ }
buildData.setBuildString(output.toString());
buildData.setCompileTime((System.nanoTime() - start) / 1E6);
if (!success)
@@ -96,17 +98,21 @@ public class JavaBuildMethod {
private boolean test() {
updateState(BuildState.TESTING);
- StringBuilder output = new StringBuilder("");
- boolean success = installer.executeAnt("test", output);
- Matcher m = JUNIT_PATTERN.matcher(output.substring(output.indexOf("Tests run"), output.indexOf("\n", output.indexOf("Tests run"))));
- if (!m.matches()) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ boolean success = true;
+ try {
+ connection.newBuild().setJvmArguments("-Duser.dir="+buildData.getServer().getDirectory()).forTasks("cleanTest", "test").setStandardOutput(output).setStandardError(output).run();
+ } catch (Exception e) {
success = false;
- System.err.println("Failed to match FAIL pattern: " + output);
- buildData.setTestDetails(new TestDetails(0, 0));
- } else {
- buildData.setTestDetails(new TestDetails(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) + Integer.parseInt(m.group(3))));
}
- buildData.setTestString(output.toString());
+ String outputString = getOutputStreamString(output);
+ Matcher m = JUNIT_PATTERN.matcher(outputString);
+ if (m.matches())
+ buildData.setTestDetails(new TestDetails(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2))));
+ else
+ buildData.setTestDetails(new TestDetails(0, 0));
+ Log.d("Tests Completed. Total: %d Failed: %d", buildData.getTestDetails().getTotal(), buildData.getTestDetails().getFailures());
+ buildData.setTestString(outputString);
if (!success)
updateState(BuildState.TEST_FAILED);
return success && !detectCancelled(buildData, callback);
@@ -114,9 +120,26 @@ public class JavaBuildMethod {
private boolean install() {
updateState(BuildState.INSTALLING);
- installer.executeAnt("jar", new StringBuilder(""));
- buildData.setJar(installer.getJar());
- return !detectCancelled(buildData, callback);
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ boolean success = true;
+ try {
+ connection.newBuild().setJvmArguments("-Duser.dir="+buildData.getServer().getDirectory()).forTasks("shadowJar").setStandardOutput(output).setStandardError(output).run();
+ } catch (Exception e) {
+ success = false;
+ }
+ if (!success)
+ updateState(BuildState.INSTALL_FAILED);
+ buildData.setJar(new File(buildData.getServer().getDirectory(), "build/libs/Holocore.jar"));
+ return success && !detectCancelled(buildData, callback);
+ }
+
+ private String getOutputStreamString(ByteArrayOutputStream output) {
+ try {
+ return output.toString("ASCII");
+ } catch (UnsupportedEncodingException e) {
+ Log.e(e);
+ return "";
+ }
}
private boolean detectCancelled(ServerBuildData buildData, InstallationCallback callback) {
diff --git a/src/com/projectswg/lightspeed/build/java_builder/RepoInstaller.java b/src/com/projectswg/lightspeed/build/java_builder/RepoInstaller.java
index cc4fdf8..19231af 100644
--- a/src/com/projectswg/lightspeed/build/java_builder/RepoInstaller.java
+++ b/src/com/projectswg/lightspeed/build/java_builder/RepoInstaller.java
@@ -31,13 +31,6 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import org.apache.tools.ant.BuildEvent;
-import org.apache.tools.ant.BuildListener;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.ProjectHelper;
-
-import com.projectswg.common.debug.Log;
-
public class RepoInstaller {
@@ -166,36 +159,4 @@ public class RepoInstaller {
return files;
}
- public boolean executeAnt(String target, StringBuilder output) {
- File buildFile = new File("build.xml");
- Project p = new Project();
- ProjectHelper helper = ProjectHelper.getProjectHelper();
- p.setProperty("java.home", getJdk().getAbsolutePath());
- p.setUserProperty("ant.file", buildFile.getAbsolutePath());
- p.setUserProperty("opdir", getRepo().getAbsolutePath());
- p.init();
- p.addReference("ant.projectHelper", helper);
- helper.parse(p, buildFile);
- p.addBuildListener(new BuildListener() {
- public void taskStarted(BuildEvent arg0) { }
- public void taskFinished(BuildEvent arg0) { }
- public void targetStarted(BuildEvent arg0) { }
- public void targetFinished(BuildEvent arg0) { }
- public void buildStarted(BuildEvent arg0) { }
- public void buildFinished(BuildEvent arg0) { }
- @Override
- public void messageLogged(BuildEvent arg0) {
- if (arg0.getPriority() <= 2)
- output.append(arg0.getMessage() + '\n');
- }
- });
- try {
- p.executeTarget(target);
- return true;
- } catch (Throwable t) {
- Log.e(t);
- return false;
- }
- }
-
}
diff --git a/src/com/projectswg/lightspeed/gui/GUIService.java b/src/com/projectswg/lightspeed/gui/GUIService.java
index 1c64c0f..c843521 100644
--- a/src/com/projectswg/lightspeed/gui/GUIService.java
+++ b/src/com/projectswg/lightspeed/gui/GUIService.java
@@ -27,14 +27,14 @@
***********************************************************************************/
package com.projectswg.lightspeed.gui;
-import javafx.application.Application;
-
import com.projectswg.Lightspeed;
import com.projectswg.common.concurrency.PswgBasicThread;
import com.projectswg.common.control.LightspeedService;
import com.projectswg.common.data.BackendData;
import com.projectswg.common.info.ConfigFile;
+import javafx.application.Application;
+
public class GUIService extends LightspeedService {
private final PswgBasicThread guiThread;
diff --git a/src/com/projectswg/lightspeed/gui/LightspeedServerPrimaryView.java b/src/com/projectswg/lightspeed/gui/LightspeedServerPrimaryView.java
index 2d06762..48d5a91 100644
--- a/src/com/projectswg/lightspeed/gui/LightspeedServerPrimaryView.java
+++ b/src/com/projectswg/lightspeed/gui/LightspeedServerPrimaryView.java
@@ -33,8 +33,8 @@ import java.util.Map;
import com.projectswg.common.concurrency.PswgBasicScheduledThread;
import com.projectswg.common.utilities.TimeUtilities;
-import com.projectswg.lightspeed.deployment.ServerDeploymentData;
import com.projectswg.lightspeed.build.ServerBuildData;
+import com.projectswg.lightspeed.deployment.ServerDeploymentData;
import com.projectswg.lightspeed.gui.GUIService.GUIData;
import com.projectswg.lightspeed.server.ServerServerData;
diff --git a/src/com/projectswg/lightspeed/server/ServerService.java b/src/com/projectswg/lightspeed/server/ServerService.java
index d3b4888..c36b5cc 100644
--- a/src/com/projectswg/lightspeed/server/ServerService.java
+++ b/src/com/projectswg/lightspeed/server/ServerService.java
@@ -33,8 +33,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.concurrency.PswgBasicScheduledThread;
import com.projectswg.common.control.LightspeedService;
import com.projectswg.common.debug.Log;
@@ -48,6 +46,8 @@ import com.projectswg.common.network.packets.response.ResponseServerListPacket;
import com.projectswg.lightspeed.git.GitInterface;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import me.joshlarson.json.JSONObject;
+
public class ServerService extends LightspeedService {
private final Set servers;
diff --git a/src/com/projectswg/lightspeed_frontend/Frontend.java b/src/com/projectswg/lightspeed_frontend/Frontend.java
index 204e61e..89a8236 100644
--- a/src/com/projectswg/lightspeed_frontend/Frontend.java
+++ b/src/com/projectswg/lightspeed_frontend/Frontend.java
@@ -31,14 +31,16 @@ import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.prefs.Preferences;
import com.projectswg.common.concurrency.PswgScheduledThreadPool;
import com.projectswg.common.concurrency.PswgThreadPool;
import com.projectswg.common.data.TestDetails;
+import com.projectswg.common.data.info.Config;
import com.projectswg.common.debug.Assert;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.Config;
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.request.RequestBuildDetailedPacket;
import com.projectswg.common.network.packets.request.RequestBuildListPacket;
@@ -60,10 +62,15 @@ import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
import com.projectswg.lightspeed_frontend.intents.InboundPacketIntent;
+import javafx.stage.Stage;
+
public class Frontend {
private final PswgThreadPool threadPool;
private final PswgScheduledThreadPool scheduledUpdater;
+ private final AtomicReference primaryStage;
+ private final AtomicBoolean canSendRequestLatestBuild;
+ private final AtomicBoolean canSendRequestLatestDeployment;
private final FrontendCommunication communication;
private final FrontendData data;
private final Preferences preferences;
@@ -71,7 +78,11 @@ public class Frontend {
public Frontend() {
this.threadPool = new PswgThreadPool(5, "frontend-thread-pool");
+ this.threadPool.setInterruptOnStop(true);
this.scheduledUpdater = new PswgScheduledThreadPool(1, "frontend-updater");
+ this.primaryStage = new AtomicReference<>(null);
+ this.canSendRequestLatestBuild = new AtomicBoolean(true);
+ this.canSendRequestLatestDeployment = new AtomicBoolean(true);
this.data = new FrontendData();
File data = new File("cfg");
data.mkdirs();
@@ -85,7 +96,7 @@ public class Frontend {
public void setAddress(InetSocketAddress address) {
Log.i("Changing remote address to %s", address);
- if (!address.equals(communication.getAddress())) {
+ if ((address != communication.getAddress() && (address == null || communication.getAddress() == null)) || !address.equals(communication.getAddress())) {
communication.setAddress(address);
Log.i("Clearing all frontend data - requesting complete reload");
data.clearAll();
@@ -93,12 +104,20 @@ public class Frontend {
}
}
+ public void setPrimaryStage(Stage stage) {
+ primaryStage.set(stage);
+ }
+
+ public Stage getPrimaryStage() {
+ return primaryStage.get();
+ }
+
public void start() {
Assert.test(communication.start());
threadPool.start();
scheduledUpdater.start();
scheduledUpdater.executeWithFixedDelay(0, 10000, () -> requestCompleteLoad());
- scheduledUpdater.executeWithFixedDelay(3000, 3000, () -> requestLatestUpdates());
+ scheduledUpdater.executeWithFixedDelay(10000, 1000, () -> requestLatestUpdates());
}
public void stop() {
@@ -166,7 +185,7 @@ public class Frontend {
send(new RequestDeploymentListPacket(serverId), callback);
}
- private void requestCompleteLoad() {
+ public void requestCompleteLoad() {
probeConnectivity(connected -> {
if (!connected) {
data.clearAll();
@@ -185,18 +204,21 @@ public class Frontend {
SharedServerData server = data.getSelectedServer();
if (server == null)
return;
- SharedBuildData lastBuild = server.getLastBuild();
- if (lastBuild != null && lastBuild.getBuildState().isInProgress()) {
- loadBuildDetailed(lastBuild.getId(), null);
+ if (canSendRequestLatestBuild.getAndSet(false)) {
+ SharedBuildData lastBuild = server.getLastBuild();
+ if (lastBuild != null && lastBuild.getBuildState().isInProgress()) {
+ loadBuildDetailed(lastBuild.getId(), null);
+ }
}
- SharedDeploymentData lastDeployment = server.getLastDeployment();
- if (lastDeployment != null) {
- loadDeploymentDetailed(lastDeployment.getId(), null);
+ if (canSendRequestLatestDeployment.getAndSet(false)) {
+ SharedDeploymentData lastDeployment = server.getLastDeployment();
+ if (lastDeployment != null) {
+ loadDeploymentDetailed(lastDeployment.getId(), null);
+ }
}
}
private void process(Packet packet) {
- new InboundPacketIntent(packet).broadcast();
if (packet instanceof ResponseServerListPacket)
processServerList((ResponseServerListPacket) packet);
else if (packet instanceof ResponseServerDetailedPacket)
@@ -209,6 +231,7 @@ public class Frontend {
processDeploymentList((ResponseDeploymentListPacket) packet);
else if (packet instanceof ResponseDeploymentDetailedPacket)
processDeploymentDetailed((ResponseDeploymentDetailedPacket) packet);
+ new InboundPacketIntent(packet).broadcast();
}
private void processServerList(ResponseServerListPacket list) {
@@ -237,6 +260,7 @@ public class Frontend {
SharedBuildData last = server.getLastBuild();
for (SharedBuildData build : list.getBuildList()) {
if (server.getBuildData(build.getId()) == null) {
+ canSendRequestLatestBuild.set(true);
server.addBuild(build);
}
}
@@ -246,6 +270,7 @@ public class Frontend {
}
private void processBuildDetailed(ResponseBuildDetailedPacket detailed) {
+ canSendRequestLatestBuild.set(true);
SharedServerData server = data.getServer(detailed.getServerId());
SharedBuildData build = server.getBuildData(detailed.getBuildId());
if (build != null) {
@@ -265,6 +290,7 @@ public class Frontend {
SharedDeploymentData last = server.getLastDeployment();
for (SharedDeploymentData deployment : list.getDeploymentList()) {
if (server.getDeploymentData(deployment.getId()) == null) {
+ canSendRequestLatestDeployment.set(true);
server.addDeployment(deployment);
}
}
@@ -274,6 +300,7 @@ public class Frontend {
}
private void processDeploymentDetailed(ResponseDeploymentDetailedPacket detailed) {
+ canSendRequestLatestDeployment.set(true);
SharedServerData server = data.getServer(detailed.getServerId());
SharedDeploymentData deployment = server.getDeploymentData(detailed.getDeploymentId());
if (deployment != null) {
diff --git a/src/com/projectswg/lightspeed_frontend/FrontendData.java b/src/com/projectswg/lightspeed_frontend/FrontendData.java
index 34e79e4..37e2d51 100644
--- a/src/com/projectswg/lightspeed_frontend/FrontendData.java
+++ b/src/com/projectswg/lightspeed_frontend/FrontendData.java
@@ -27,14 +27,15 @@
***********************************************************************************/
package com.projectswg.lightspeed_frontend;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-
import com.projectswg.common.javafx.PSWGObjectProperty;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
import com.projectswg.lightspeed_frontend.data.SharedDeploymentData;
import com.projectswg.lightspeed_frontend.data.SharedServerData;
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
public class FrontendData {
private final ObservableList servers;
@@ -54,6 +55,10 @@ public class FrontendData {
}
public void clearAll() {
+ if (!Platform.isFxApplicationThread()) {
+ Platform.runLater(() -> clearAll());
+ return;
+ }
servers.clear();
selectedServer.set(null);
selectedBuild.set(null);
diff --git a/src/com/projectswg/lightspeed_frontend/LightspeedFrontendGUI.java b/src/com/projectswg/lightspeed_frontend/LightspeedFrontendGUI.java
index 7d83da1..1340e64 100644
--- a/src/com/projectswg/lightspeed_frontend/LightspeedFrontendGUI.java
+++ b/src/com/projectswg/lightspeed_frontend/LightspeedFrontendGUI.java
@@ -1,30 +1,6 @@
/***********************************************************************************
-* 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 . *
-* *
-***********************************************************************************/
+ * 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.lightspeed_frontend;
import java.io.File;
@@ -61,7 +37,7 @@ public class LightspeedFrontendGUI extends Application {
frontend.start();
}
- public static void main(String [] args) {
+ public static void main(String[] args) {
ResourceUtilities.setPrimarySource(LightspeedFrontendGUI.class);
Log.addWrapper(new ConsoleLogWrapper(LogLevel.VERBOSE));
try {
@@ -75,7 +51,8 @@ public class LightspeedFrontendGUI extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
IntentManager.getInstance().initialize();
- primaryView = (LightspeedPrimaryView) FXMLUtilities.loadFxml("PrimaryView.fxml", Locale.ENGLISH);
+ frontend.setPrimaryStage(primaryStage);
+ primaryView = (LightspeedPrimaryView) FXMLUtilities.loadFxmlAsClassResource("PrimaryView.fxml", Locale.ENGLISH);
Parent root = primaryView.getRoot();
primaryStage.setTitle("Lightspeed Frontend");
primaryStage.setScene(new Scene(root));
@@ -85,6 +62,7 @@ public class LightspeedFrontendGUI extends Application {
primaryStage.setOnCloseRequest((we) -> {
close(we);
primaryStage.close();
+ System.exit(0);
});
}
diff --git a/src/com/projectswg/lightspeed_frontend/LightspeedFrontendText.java b/src/com/projectswg/lightspeed_frontend/LightspeedFrontendText.java
index 501e79d..ce43f26 100644
--- a/src/com/projectswg/lightspeed_frontend/LightspeedFrontendText.java
+++ b/src/com/projectswg/lightspeed_frontend/LightspeedFrontendText.java
@@ -38,9 +38,22 @@ import com.projectswg.common.debug.Log;
import com.projectswg.common.debug.Log.LogLevel;
import com.projectswg.common.debug.log_wrapper.ConsoleLogWrapper;
import com.projectswg.common.network.packets.Packet;
-import com.projectswg.common.network.packets.post.*;
-import com.projectswg.common.network.packets.request.*;
-import com.projectswg.common.network.packets.response.*;
+import com.projectswg.common.network.packets.post.PostBuildPacket;
+import com.projectswg.common.network.packets.post.PostDeployPacket;
+import com.projectswg.common.network.packets.post.PostStopBuildPacket;
+import com.projectswg.common.network.packets.post.PostStopDeployPacket;
+import com.projectswg.common.network.packets.request.RequestBuildDetailedPacket;
+import com.projectswg.common.network.packets.request.RequestBuildListPacket;
+import com.projectswg.common.network.packets.request.RequestDeploymentDetailedPacket;
+import com.projectswg.common.network.packets.request.RequestDeploymentListPacket;
+import com.projectswg.common.network.packets.request.RequestPacket;
+import com.projectswg.common.network.packets.request.RequestServerDetailedPacket;
+import com.projectswg.common.network.packets.request.RequestServerListPacket;
+import com.projectswg.common.network.packets.response.ResponseBuildDetailedPacket;
+import com.projectswg.common.network.packets.response.ResponseBuildListPacket;
+import com.projectswg.common.network.packets.response.ResponseDeploymentDetailedPacket;
+import com.projectswg.common.network.packets.response.ResponseDeploymentListPacket;
+import com.projectswg.common.network.packets.response.ResponseServerListPacket;
import com.projectswg.common.utilities.TimeUtilities;
import com.projectswg.lightspeed_frontend.communication.FrontendCommunication;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
diff --git a/src/com/projectswg/lightspeed_frontend/communication/FrontendCommunication.java b/src/com/projectswg/lightspeed_frontend/communication/FrontendCommunication.java
index 0661fd5..1435458 100644
--- a/src/com/projectswg/lightspeed_frontend/communication/FrontendCommunication.java
+++ b/src/com/projectswg/lightspeed_frontend/communication/FrontendCommunication.java
@@ -27,14 +27,12 @@
***********************************************************************************/
package com.projectswg.lightspeed_frontend.communication;
-import java.io.File;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.prefs.Preferences;
import com.projectswg.common.debug.Assert;
import com.projectswg.common.debug.Log;
-import com.projectswg.common.info.Config;
import com.projectswg.common.network.packets.Packet;
import com.projectswg.lightspeed_frontend.Frontend;
@@ -49,14 +47,6 @@ public class FrontendCommunication {
this.frontend = frontend;
this.running = new AtomicBoolean(false);
this.callback = null;
- Config config = frontend.getConfig();
- if (config.getBoolean("SECURITY", false)) {
- String keystore = config.getString("KEYSTORE", "");
- if (!keystore.isEmpty()) {
- HttpClient.setupSSL(new File(keystore), config.getString("KEYSTORE-PASS", ""));
- HttpClient.setupUserPass(config.getString("USERNAME", ""), config.getString("PASSWORD", ""));
- }
- }
Preferences comm = frontend.getPreferences().node("communication");
this.address = new InetSocketAddress(comm.get("inet-addr", "localhost"), comm.getInt("inet-port", 44444));
}
@@ -71,8 +61,13 @@ public class FrontendCommunication {
public void setAddress(InetSocketAddress address) {
Preferences comm = frontend.getPreferences().node("communication");
- comm.put("inet-addr", address.getHostString());
- comm.putInt("inet-port", address.getPort());
+ if (address == null) {
+ comm.remove("inet-addr");
+ comm.remove("inet-port");
+ } else {
+ comm.put("inet-addr", address.getHostString());
+ comm.putInt("inet-port", address.getPort());
+ }
this.address = address;
}
diff --git a/src/com/projectswg/lightspeed_frontend/communication/HttpClient.java b/src/com/projectswg/lightspeed_frontend/communication/HttpClient.java
index 2da6e4b..5eb543b 100644
--- a/src/com/projectswg/lightspeed_frontend/communication/HttpClient.java
+++ b/src/com/projectswg/lightspeed_frontend/communication/HttpClient.java
@@ -37,6 +37,7 @@ import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
+import java.net.SocketException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@@ -49,11 +50,9 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManagerFactory;
-import me.joshlarson.json.JSON;
-import me.joshlarson.json.JSONObject;
-
import com.projectswg.common.debug.Log;
import com.projectswg.common.network.packets.Packet;
import com.projectswg.common.network.packets.PacketType;
@@ -62,6 +61,9 @@ import com.projectswg.common.network.packets.connection.ConnectionProbePacket;
import com.projectswg.common.network.packets.post.PostPacket;
import com.projectswg.common.network.packets.request.RequestPacket;
+import me.joshlarson.json.JSON;
+import me.joshlarson.json.JSONObject;
+
public class HttpClient {
private static final AtomicBoolean SSL = new AtomicBoolean(false);
@@ -69,6 +71,10 @@ public class HttpClient {
private static final AtomicReference PASSWORD = new AtomicReference<>("");
public static void setupSSL(File keystoreFile, String password) {
+ if (keystoreFile == null || password == null) {
+ SSL.set(false);
+ return;
+ }
try {
InputStream keystoreStream = new FileInputStream(keystoreFile);
char[] trustPassword = password.toCharArray();
@@ -95,6 +101,10 @@ public class HttpClient {
PASSWORD.set(pass);
}
+ public static boolean isSSLEnabled() {
+ return SSL.get();
+ }
+
public static boolean probeConnection(InetSocketAddress address) {
return requestPacket(address, new ConnectionProbePacket()) != null;
}
@@ -111,9 +121,18 @@ public class HttpClient {
}
PacketType type = PacketType.valueOf(obj.getString("type"));
return Packet.inflate(obj, type);
+ } catch (SSLHandshakeException e) {
+ Log.w("SSL failed to %s", address);
+ return null;
} catch (ConnectException e) {
Log.w("Failed to connect to %s", address);
return null;
+ } catch (SocketException e) {
+ if (e.getMessage() != null && e.getMessage().contains("end of file"))
+ Log.w("HTTP failed to %s", address);
+ else
+ Log.e(e);
+ return null;
} catch (IOException e) {
Log.e(e);
}
@@ -123,25 +142,32 @@ public class HttpClient {
public static String requestString(InetSocketAddress address, Packet packet) throws IOException {
URL url = new URL(generateURL(address, packet));
HttpURLConnection con = (HttpURLConnection) url.openConnection();
+
if (SSL.get()) {
String encoded = Base64.getEncoder().encodeToString((USERNAME.get()+":"+PASSWORD.get()).getBytes(StandardCharsets.UTF_8));
con.setRequestProperty("Authorization", "Basic "+encoded);
}
-
con.setRequestMethod((packet instanceof PostPacket) ? "POST" : "GET");
con.setRequestProperty("User-Agent", "LightspeedFrontend");
- int responseCode = con.getResponseCode();
- if (responseCode != 200)
- return "RESPONSE CODE " + responseCode;
-
+ return readResponse(con);
+ }
+
+ private static String readResponse(HttpURLConnection connection) throws IOException {
StringBuilder response = new StringBuilder("");
- try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
+ InputStream inputStream = connection.getInputStream();
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(inputStream))) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
}
+
+ int responseCode = connection.getResponseCode();
+ inputStream.close();
+
+ if (responseCode != 200)
+ return "RESPONSE CODE " + responseCode;
return response.toString();
}
diff --git a/src/com/projectswg/lightspeed_frontend/data/SharedDeploymentData.java b/src/com/projectswg/lightspeed_frontend/data/SharedDeploymentData.java
index 3cf7f1e..1be347d 100644
--- a/src/com/projectswg/lightspeed_frontend/data/SharedDeploymentData.java
+++ b/src/com/projectswg/lightspeed_frontend/data/SharedDeploymentData.java
@@ -33,7 +33,7 @@ public class SharedDeploymentData {
private SharedBuildData build;
private long startTime;
private long endTime;
- private String output;
+ private StringBuilder output;
private DeploymentState state;
public SharedDeploymentData(long id, SharedBuildData build) {
@@ -41,7 +41,7 @@ public class SharedDeploymentData {
this.build = build;
this.startTime = 0;
this.endTime = 0;
- this.output = "";
+ this.output = new StringBuilder("");
this.state = DeploymentState.CREATED;
}
@@ -68,7 +68,7 @@ public class SharedDeploymentData {
}
public String getOutput() {
- return output;
+ return output.toString();
}
public DeploymentState getDeploymentState() {
@@ -88,21 +88,24 @@ public class SharedDeploymentData {
}
public void setOutput(String output) {
- this.output = output;
+ this.output.setLength(0);
+ this.output.append(output);
}
public void appendOutput(String line) {
- this.output += line + '\n';
+ this.output.append(line);
}
public void setDeploymentState(DeploymentState state) {
this.state = state;
}
+ @Override
public int hashCode() {
return Long.hashCode(id);
}
+ @Override
public boolean equals(Object o) {
if (o == null)
return false;
@@ -111,6 +114,7 @@ public class SharedDeploymentData {
return ((SharedDeploymentData) o).getId() == id;
}
+ @Override
public String toString() {
return String.format("SharedDeploymentData[id=%d, build=%d, server=%s, start_time=%d, end_time=%d]", id, getBuild().getId(), getServer().getName(), startTime, endTime);
}
diff --git a/res/fxml/PrimaryView.css b/src/com/projectswg/lightspeed_frontend/fxml/PrimaryView.css
similarity index 100%
rename from res/fxml/PrimaryView.css
rename to src/com/projectswg/lightspeed_frontend/fxml/PrimaryView.css
diff --git a/res/fxml/PrimaryView.fxml b/src/com/projectswg/lightspeed_frontend/fxml/PrimaryView.fxml
similarity index 93%
rename from res/fxml/PrimaryView.fxml
rename to src/com/projectswg/lightspeed_frontend/fxml/PrimaryView.fxml
index 5e12401..16f5817 100644
--- a/res/fxml/PrimaryView.fxml
+++ b/src/com/projectswg/lightspeed_frontend/fxml/PrimaryView.fxml
@@ -40,6 +40,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/fxml/primary_tabs/Build.css b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Build.css
similarity index 100%
rename from res/fxml/primary_tabs/Build.css
rename to src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Build.css
diff --git a/res/fxml/primary_tabs/Build.fxml b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Build.fxml
similarity index 100%
rename from res/fxml/primary_tabs/Build.fxml
rename to src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Build.fxml
diff --git a/res/fxml/primary_tabs/Deployment.css b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Deployment.css
similarity index 100%
rename from res/fxml/primary_tabs/Deployment.css
rename to src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Deployment.css
diff --git a/res/fxml/primary_tabs/Deployment.fxml b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Deployment.fxml
similarity index 96%
rename from res/fxml/primary_tabs/Deployment.fxml
rename to src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Deployment.fxml
index 6594467..29ecde7 100644
--- a/res/fxml/primary_tabs/Deployment.fxml
+++ b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Deployment.fxml
@@ -45,6 +45,7 @@
+
diff --git a/res/fxml/primary_tabs/General.css b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/General.css
similarity index 100%
rename from res/fxml/primary_tabs/General.css
rename to src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/General.css
diff --git a/res/fxml/primary_tabs/General.fxml b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/General.fxml
similarity index 100%
rename from res/fxml/primary_tabs/General.fxml
rename to src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/General.fxml
diff --git a/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Settings.css b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Settings.css
new file mode 100644
index 0000000..37a1e66
--- /dev/null
+++ b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Settings.css
@@ -0,0 +1,22 @@
+.white-label {
+ -fx-text-fill: #FFFFFF;
+}
+
+.red-label {
+ -fx-text-fill: #ff1e1e;
+}
+
+.green-label {
+ -fx-text-fill: #04ff00;
+}
+
+.log {
+ -fx-text-fill: #FFFFFF;
+}
+
+.log .content {
+ -fx-background: #3F4042;
+ -fx-background-color: #3F4042;
+ -fx-border-color: white;
+ -fx-border-width: 1 0 1 0;
+}
diff --git a/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Settings.fxml b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Settings.fxml
new file mode 100644
index 0000000..60dfeab
--- /dev/null
+++ b/src/com/projectswg/lightspeed_frontend/fxml/primary_tabs/Settings.fxml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/projectswg/lightspeed_frontend/gui/InternalWindow.java b/src/com/projectswg/lightspeed_frontend/gui/InternalWindow.java
index 72cc27e..6a2ed29 100644
--- a/src/com/projectswg/lightspeed_frontend/gui/InternalWindow.java
+++ b/src/com/projectswg/lightspeed_frontend/gui/InternalWindow.java
@@ -29,6 +29,10 @@ package com.projectswg.lightspeed_frontend.gui;
import java.awt.Color;
+import javax.swing.UIManager;
+
+import com.projectswg.common.debug.Log;
+
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
@@ -44,10 +48,6 @@ import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
-import javax.swing.UIManager;
-
-import com.projectswg.common.debug.Log;
-
public class InternalWindow extends Region {
diff --git a/src/com/projectswg/lightspeed_frontend/gui/LightspeedPrimaryView.java b/src/com/projectswg/lightspeed_frontend/gui/LightspeedPrimaryView.java
index 8a3da49..20ce282 100644
--- a/src/com/projectswg/lightspeed_frontend/gui/LightspeedPrimaryView.java
+++ b/src/com/projectswg/lightspeed_frontend/gui/LightspeedPrimaryView.java
@@ -97,9 +97,9 @@ public class LightspeedPrimaryView implements FXMLController {
@Override
public void initialize(URL location, ResourceBundle resources) {
FXMLUtilities.onFxmlLoaded(this);
- FXMLUtilities.loadFxml("primary_tabs/General.fxml", Locale.ENGLISH);
- FXMLUtilities.loadFxml("primary_tabs/Build.fxml", Locale.ENGLISH);
- FXMLUtilities.loadFxml("primary_tabs/Deployment.fxml", Locale.ENGLISH);
+ FXMLUtilities.loadFxmlAsClassResource("primary_tabs/General.fxml", Locale.ENGLISH);
+ FXMLUtilities.loadFxmlAsClassResource("primary_tabs/Build.fxml", Locale.ENGLISH);
+ FXMLUtilities.loadFxmlAsClassResource("primary_tabs/Deployment.fxml", Locale.ENGLISH);
ipAddressText.setText(frontend.getCommunication().getAddress().getHostString());
portText.setText(Integer.toString(frontend.getCommunication().getAddress().getPort()));
validIpRegion.setBackground(validIpBackground);
diff --git a/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/BuildTab.java b/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/BuildTab.java
index c0694eb..6361f5e 100644
--- a/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/BuildTab.java
+++ b/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/BuildTab.java
@@ -42,8 +42,8 @@ import com.projectswg.common.utilities.TimeUtilities;
import com.projectswg.lightspeed_frontend.Frontend;
import com.projectswg.lightspeed_frontend.LightspeedFrontendGUI;
import com.projectswg.lightspeed_frontend.data.SharedBuildData;
-import com.projectswg.lightspeed_frontend.data.SharedServerData;
import com.projectswg.lightspeed_frontend.data.SharedBuildData.BuildState;
+import com.projectswg.lightspeed_frontend.data.SharedServerData;
import com.projectswg.lightspeed_frontend.intents.InboundPacketIntent;
import javafx.application.Platform;
diff --git a/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/DeploymentTab.java b/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/DeploymentTab.java
index 2990af2..a001a0d 100644
--- a/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/DeploymentTab.java
+++ b/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/DeploymentTab.java
@@ -27,11 +27,17 @@
***********************************************************************************/
package com.projectswg.lightspeed_frontend.gui.primary_tabs;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
+
import com.projectswg.common.concurrency.PswgScheduledThreadPool;
import com.projectswg.common.control.IntentManager;
import com.projectswg.common.debug.Log;
@@ -50,6 +56,7 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Parent;
+import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
@@ -76,6 +83,8 @@ public class DeploymentTab implements FXMLController {
@FXML
private Label uptimeText;
@FXML
+ private Button logDownloadButton;
+ @FXML
private TextArea logTextArea;
private final PswgScheduledThreadPool scheduledUpdater;
@@ -116,6 +125,7 @@ public class DeploymentTab implements FXMLController {
frontend.loadDeploymentDetailed(val.getId(), response -> Platform.runLater(() -> updateDeploymentDetails()));
}
});
+ logDownloadButton.setOnAction(eh -> downloadLog());
IntentManager.getInstance().registerForIntent(InboundPacketIntent.class, ipi -> Platform.runLater(() -> updateDeploymentList(false)));
this.frontend.getData().getSelectedServerProperty().addListener((val, prev, next) -> Platform.runLater(() -> updateDeploymentList(true)));
updateDeploymentList(true);
@@ -249,7 +259,7 @@ public class DeploymentTab implements FXMLController {
double pos = logTextArea.getScrollTop();
int anchor = logTextArea.getAnchor();
int caret = logTextArea.getCaretPosition();
- logTextArea.setText(selectedDeployment.getOutput());
+ logTextArea.setText(tail(selectedDeployment.getOutput(), 100));
if (anchor != caret) {
logTextArea.setScrollTop(pos);
logTextArea.selectRange(anchor, caret);
@@ -259,18 +269,49 @@ public class DeploymentTab implements FXMLController {
}
}
+ private void downloadLog() {
+ SharedDeploymentData selectedDeployment = frontend.getData().getSelectedDeployment();
+ if (selectedDeployment == null || selectedDeployment.getStartTime() == 0) {
+ // TODO: Simple little popup saying cannot download
+ } else {
+ try (FileOutputStream fos = new FileOutputStream(createDownloadLogFile(selectedDeployment))) {
+ fos.write(selectedDeployment.getOutput().getBytes(StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ Log.e(e);
+ }
+ }
+ }
+
+ private File createDownloadLogFile(SharedDeploymentData selectedDeployment) {
+ String folder = ".";
+ String time = new SimpleDateFormat("MMdd-HH:mm:ss").format(System.currentTimeMillis());
+ return new File(folder, String.format("deployment-log-ID%d-TIME%s.log", selectedDeployment.getId(), time));
+ }
+
+ private String tail(String str, int n) {
+ int index = str.length();
+ for (int i = 0; i < n && index > 0; i++) {
+ index = str.lastIndexOf('\n', index-1);
+ }
+ if (index <= 0)
+ return str;
+ return str.substring(index);
+ }
+
public interface SelectedDeploymentChangedCallback {
void onDeploymentChanged(SharedDeploymentData deployment);
}
private class DeploymentStringConverter extends StringConverter {
+ @Override
public String toString(SharedDeploymentData deployment) {
if (deployment == NULL_DEPLOY)
return "latest";
return "D " + deployment.getId() + " - B " + deployment.getBuild().getId();
}
+ @Override
public SharedDeploymentData fromString(String string) {
if (string.isEmpty() || string.equals("latest"))
return NULL_DEPLOY;
diff --git a/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/SettingsTab.java b/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/SettingsTab.java
new file mode 100644
index 0000000..a7069c6
--- /dev/null
+++ b/src/com/projectswg/lightspeed_frontend/gui/primary_tabs/SettingsTab.java
@@ -0,0 +1,203 @@
+/***********************************************************************************
+* 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.lightspeed_frontend.gui.primary_tabs;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ResourceBundle;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+import com.projectswg.common.debug.Log;
+import com.projectswg.common.javafx.FXMLController;
+import com.projectswg.common.javafx.FXMLUtilities;
+import com.projectswg.lightspeed_frontend.Frontend;
+import com.projectswg.lightspeed_frontend.LightspeedFrontendGUI;
+import com.projectswg.lightspeed_frontend.communication.HttpClient;
+
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.stage.FileChooser;
+
+public class SettingsTab implements FXMLController {
+
+ private static final String DEFAULT_KEYSTORE_PATH = "No Keystore Defined";
+
+ @FXML
+ private Parent rootSettings;
+ @FXML
+ private CheckBox securityCheckBox;
+ @FXML
+ private Button keystoreButton;
+ @FXML
+ private PasswordField keystorePasswordTextField;
+ @FXML
+ private TextField usernameTextField;
+ @FXML
+ private PasswordField passwordTextField;
+
+ private final Frontend frontend;
+
+ public SettingsTab() {
+ this.frontend = LightspeedFrontendGUI.FRONTEND;
+ }
+
+ @Override
+ public Parent getRoot() {
+ return rootSettings;
+ }
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ FXMLUtilities.onFxmlLoaded(this);
+ loadSettings();
+ updateAccountInformation();
+ updateKeystore();
+ keystoreButton.setOnAction(e -> setKeystorePathPopup());
+ securityCheckBox.selectedProperty().addListener(l -> updateKeystore());
+ keystoreButton.textProperty().addListener(l -> updateKeystore());
+ keystorePasswordTextField.textProperty().addListener(l -> updateKeystore());
+ usernameTextField.textProperty().addListener(l -> updateAccountInformation());
+ passwordTextField.textProperty().addListener(l -> updateAccountInformation());
+ }
+
+ @Override
+ public void terminate() {
+ saveSettings();
+ }
+
+ private void updateKeystore() {
+ saveSettings();
+ if (!isSecure()) {
+ HttpClient.setupSSL(null, null);
+ frontend.requestCompleteLoad();
+ return;
+ }
+ String path = getKeystorePath();
+ String pass = getKeystorePassword();
+ File keystore = new File(path);
+ if (path.isEmpty() || !keystore.isFile()) {
+ HttpClient.setupSSL(null, null);
+ frontend.requestCompleteLoad();
+ Log.w("Invalid keystore file: '%s'", path);
+ return;
+ }
+ HttpClient.setupSSL(keystore, pass);
+ frontend.requestCompleteLoad();
+ }
+
+ private void updateAccountInformation() {
+ saveSettings();
+ HttpClient.setupUserPass(getUsername(), getPassword());
+ if (HttpClient.isSSLEnabled())
+ frontend.requestCompleteLoad();
+ }
+
+ private boolean isSecure() {
+ return securityCheckBox.isSelected();
+ }
+
+ private String getKeystorePath() {
+ String path = keystoreButton.getText();
+ if (path.equals(DEFAULT_KEYSTORE_PATH))
+ return "";
+ return path;
+ }
+
+ private String getKeystorePassword() {
+ return keystorePasswordTextField.getText();
+ }
+
+ private String getUsername() {
+ return usernameTextField.getText();
+ }
+
+ private String getPassword() {
+ return passwordTextField.getText();
+ }
+
+ private void setSecure(boolean secure) {
+ securityCheckBox.setSelected(secure);
+ }
+
+ private void setKeystorePath(String path) {
+ if (path.isEmpty())
+ keystoreButton.setText(DEFAULT_KEYSTORE_PATH);
+ else
+ keystoreButton.setText(path);
+ }
+
+ private void setKeystorePassword(String pass) {
+ keystorePasswordTextField.setText(pass);
+ }
+
+ private void setUsername(String username) {
+ usernameTextField.setText(username);
+ }
+
+ private void setPassword(String password) {
+ passwordTextField.setText(password);
+ }
+
+ private void loadSettings() {
+ Preferences settings = frontend.getPreferences().node("settings");
+ setSecure(settings.getBoolean("SECURE", false));
+ setKeystorePath(settings.get("KEYSTORE-PATH", ""));
+ setKeystorePassword(settings.get("KEYSTORE-PASS", ""));
+ setUsername(settings.get("USERNAME", ""));
+ setPassword(settings.get("PASSWORD", ""));
+ }
+
+ private void saveSettings() {
+ Preferences settings = frontend.getPreferences().node("settings");
+ settings.putBoolean("SECURE", isSecure());
+ settings.put("KEYSTORE-PATH", getKeystorePath());
+ settings.put("KEYSTORE-PASS", getKeystorePassword());
+ settings.put("USERNAME", getUsername());
+ settings.put("PASSWORD", getPassword());
+ try {
+ settings.flush();
+ } catch (BackingStoreException e) {
+ Log.e(e);
+ }
+ }
+
+ private void setKeystorePathPopup() {
+ FileChooser fileChooser = new FileChooser();
+ fileChooser.setTitle("Set the keystore path");
+ File file = fileChooser.showOpenDialog(frontend.getPrimaryStage());
+ if (file == null || !file.isFile())
+ return;
+ setKeystorePath(file.getAbsolutePath());
+ }
+
+}
diff --git a/test/com/projectswg/lightspeed/TestLightspeed.java b/test/com/projectswg/lightspeed/TestLightspeed.java
deleted file mode 100644
index b217c68..0000000
--- a/test/com/projectswg/lightspeed/TestLightspeed.java
+++ /dev/null
@@ -1,40 +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.lightspeed;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-@RunWith(Suite.class)
-@SuiteClasses({
-
-})
-public class TestLightspeed {
-
-}