diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1e663f8
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: main.extensions.examples.AdminOnConnect
+
diff --git a/src/main/extensions/Extension.java b/src/main/extensions/Extension.java
index ee236e4..9c57b87 100644
--- a/src/main/extensions/Extension.java
+++ b/src/main/extensions/Extension.java
@@ -4,10 +4,7 @@ import main.protocol.HMessage;
import main.protocol.HPacket;
import main.ui.extensions.Extensions;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
@@ -63,7 +60,15 @@ public abstract class Extension {
while (!gEarthExtensionServer.isClosed()) {
- int length = dIn.readInt();
+ int length;
+ try {
+ length = dIn.readInt();
+ }
+ catch(EOFException exception) {
+ //g-earth closed the extension
+ break;
+ }
+
byte[] headerandbody = new byte[length + 4];
int amountRead = 0;
@@ -142,10 +147,11 @@ public abstract class Extension {
}
}
-
+ System.out.println("Extension closed");
} catch (IOException | ArrayIndexOutOfBoundsException e) {
- e.printStackTrace();
+ System.err.println("Connection failed; is G-Earth open?");
+// e.printStackTrace();
}
finally {
if (gEarthExtensionServer != null && !gEarthExtensionServer.isClosed()) {
diff --git a/src/main/extensions/examples/AdminOnConnect.java b/src/main/extensions/examples/AdminOnConnect.java
index 2508549..11f1dde 100644
--- a/src/main/extensions/examples/AdminOnConnect.java
+++ b/src/main/extensions/examples/AdminOnConnect.java
@@ -20,7 +20,7 @@ public class AdminOnConnect extends Extension {
private boolean done = true;
protected void init() {
- intercept(HMessage.Side.TOCLIENT, -1, message -> {
+ intercept(HMessage.Side.TOCLIENT, message -> {
if (!done) {
HPacket packet = message.getPacket();
if (packet.length() == 11) {
diff --git a/src/main/ui/extensions/Extensions.fxml b/src/main/ui/extensions/Extensions.fxml
index 153d095..b07e03e 100644
--- a/src/main/ui/extensions/Extensions.fxml
+++ b/src/main/ui/extensions/Extensions.fxml
@@ -83,7 +83,7 @@
-
+
diff --git a/src/main/ui/extensions/Extensions.java b/src/main/ui/extensions/Extensions.java
index d8ab9d3..336ef03 100644
--- a/src/main/ui/extensions/Extensions.java
+++ b/src/main/ui/extensions/Extensions.java
@@ -9,10 +9,19 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
+import javafx.stage.FileChooser;
import main.Main;
import main.protocol.*;
import main.ui.SubForm;
+import main.ui.extensions.executer.ExecutionInfo;
+import main.ui.extensions.executer.ExtensionRunner;
+import main.ui.extensions.executer.ExtensionRunnerFactory;
+import main.ui.scheduler.ScheduleItem;
+import sun.misc.ExtensionInfo;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.*;
@@ -108,6 +117,9 @@ public class Extensions extends SubForm {
public GridPane header_ext;
public ScrollPane scroller;
+ private ExtensionRunner extensionRunner = null;
+ private GEarthExtensionsRegistrer extensionsRegistrer = null;
+
public static class OUTGOING_MESSAGES_IDS {
public static final int ONDOUBLECLICK = 1;
public static final int INFOREQUEST = 2; // backend: implemented
@@ -138,6 +150,8 @@ public class Extensions extends SubForm {
}
protected void onParentSet() {
+
+
getHConnection().addStateChangeListener((oldState, newState) -> {
if (newState == HConnection.State.CONNECTED) {
for (GEarthExtension extension : gEarthExtensions) {
@@ -217,7 +231,6 @@ public class Extensions extends SubForm {
});
- GEarthExtensionsRegistrer extensionsRegistrer = null;
HashMap messageListeners = new HashMap<>();
try {
extensionsRegistrer = new GEarthExtensionsRegistrer(new GEarthExtensionsRegistrer.ExtensionRegisterObserver() {
@@ -287,9 +300,22 @@ public class Extensions extends SubForm {
ext_port.setText(extensionsRegistrer.getPort()+"");
// System.out.println("Extension server registered on port: " + extensionsRegistrer.getPort());
+
+ extensionRunner = ExtensionRunnerFactory.get();
+ extensionRunner.runAllExtensions(extensionsRegistrer.getPort());
}
public void installBtnClicked(ActionEvent actionEvent) {
+ List list = new ArrayList<>();
+
+ FileChooser fileChooser = new FileChooser();
+ fileChooser.setTitle("Install extension");
+ fileChooser.getExtensionFilters().addAll(
+ new FileChooser.ExtensionFilter("G-Earth extensions", ExecutionInfo.ALLOWEDEXTENSIONTYPES));
+ File selectedFile = fileChooser.showOpenDialog(parentController.getStage());
+ if (selectedFile != null) {
+ extensionRunner.installAndRunExtension(selectedFile.getPath(), extensionsRegistrer.getPort());
+ }
}
}
diff --git a/src/main/ui/extensions/executer/ExecutionInfo.java b/src/main/ui/extensions/executer/ExecutionInfo.java
new file mode 100644
index 0000000..ef56945
--- /dev/null
+++ b/src/main/ui/extensions/executer/ExecutionInfo.java
@@ -0,0 +1,32 @@
+package main.ui.extensions.executer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by Jonas on 22/09/18.
+ */
+public class ExecutionInfo {
+
+ private static Map extensionTypeToExecutionCommand;
+ public final static List ALLOWEDEXTENSIONTYPES;
+ public final static String EXTENSIONSDIRECTORY = "Extensions";
+
+ static {
+ extensionTypeToExecutionCommand = new HashMap<>();
+ extensionTypeToExecutionCommand.put("*.jar","java -jar {path} -p {port}");
+ extensionTypeToExecutionCommand.put("*.py","python {path} -p {port}");
+ extensionTypeToExecutionCommand.put("*.py3","python3 {path} -p {port}");
+ extensionTypeToExecutionCommand.put("*.sh","{path} -p {port}");
+ extensionTypeToExecutionCommand.put("*.exe","{path} -p {port}");
+
+ ALLOWEDEXTENSIONTYPES = new ArrayList<>(extensionTypeToExecutionCommand.keySet());
+ }
+
+ public static String getExecutionCommand(String type) {
+ return extensionTypeToExecutionCommand.get(type);
+ }
+
+}
diff --git a/src/main/ui/extensions/executer/ExtensionRunner.java b/src/main/ui/extensions/executer/ExtensionRunner.java
new file mode 100644
index 0000000..2ae533a
--- /dev/null
+++ b/src/main/ui/extensions/executer/ExtensionRunner.java
@@ -0,0 +1,18 @@
+package main.ui.extensions.executer;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by Jonas on 21/09/18.
+ */
+public interface ExtensionRunner {
+
+ void runAllExtensions(int port);
+
+ void installAndRunExtension(String path, int port);
+
+}
diff --git a/src/main/ui/extensions/executer/ExtensionRunnerFactory.java b/src/main/ui/extensions/executer/ExtensionRunnerFactory.java
new file mode 100644
index 0000000..2ae174d
--- /dev/null
+++ b/src/main/ui/extensions/executer/ExtensionRunnerFactory.java
@@ -0,0 +1,14 @@
+package main.ui.extensions.executer;
+
+import main.misc.OSValidator;
+
+/**
+ * Created by Jonas on 22/09/18.
+ */
+public class ExtensionRunnerFactory {
+
+ public static ExtensionRunner get() {
+
+ return new NormalExtensionRunner();
+ }
+}
diff --git a/src/main/ui/extensions/executer/NormalExtensionRunner.java b/src/main/ui/extensions/executer/NormalExtensionRunner.java
new file mode 100644
index 0000000..38dc8c4
--- /dev/null
+++ b/src/main/ui/extensions/executer/NormalExtensionRunner.java
@@ -0,0 +1,110 @@
+package main.ui.extensions.executer;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.*;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Created by Jonas on 22/09/18.
+ */
+public class NormalExtensionRunner implements ExtensionRunner {
+
+ @Override
+ public void runAllExtensions(int port) {
+ if (dirExists(ExecutionInfo.EXTENSIONSDIRECTORY)){
+ File folder =
+ new File(FileSystems.getDefault().getPath(".").toString() +
+ FileSystems.getDefault().getSeparator() +
+ ExecutionInfo.EXTENSIONSDIRECTORY);
+
+ File[] childs = folder.listFiles();
+
+ for (File file : childs) {
+ tryRunExtension(file.getPath(), port);
+ }
+ }
+ }
+
+ @Override
+ public void installAndRunExtension(String path, int port) {
+ if (!dirExists(ExecutionInfo.EXTENSIONSDIRECTORY)) {
+ createDirectory(ExecutionInfo.EXTENSIONSDIRECTORY);
+ }
+
+
+ String name = Paths.get(path).getFileName().toString();
+ String[] split = name.split("\\.");
+ String ext = "*." + split[split.length - 1];
+
+ String realname = String.join(".",Arrays.copyOf(split, split.length-1));
+ String newname = realname + "-" + getRandomString() + ext.substring(1);
+
+
+ Path originalPath = Paths.get(path);
+ Path newPath = Paths.get(
+ FileSystems.getDefault().getPath(".").toString(),
+ ExecutionInfo.EXTENSIONSDIRECTORY,
+ newname
+ );
+
+ try {
+ Files.copy(
+ originalPath,
+ newPath
+ );
+
+ addExecPermission(newPath.toString());
+ tryRunExtension(newPath.toString(), port);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+
+ }
+
+ private void tryRunExtension(String path, int port) {
+ try {
+ Runtime.getRuntime().exec(
+ ExecutionInfo.getExecutionCommand(getFileExtension(path))
+ .replace("{path}", path)
+ .replace("{port}", port+"")
+ );
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void addExecPermission(String path) {
+ //not needed at first sight
+ }
+
+ private String getFileExtension(String path) {
+ String name = Paths.get(path).getFileName().toString();
+ String[] split = name.split("\\.");
+ return "*." + split[split.length - 1];
+ }
+ private boolean dirExists(String dir) {
+ return Files.isDirectory(Paths.get(FileSystems.getDefault().getPath(".").toString(), dir));
+ }
+ private void createDirectory(String dir) {
+ if (!dirExists(dir)) {
+ try {
+ Files.createDirectories(Paths.get(FileSystems.getDefault().getPath(".").toString(), dir));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ private String getRandomString() {
+ StringBuilder builder = new StringBuilder();
+ Random r = new Random();
+ for (int i = 0; i < 10; i++) {
+ builder.append(r.nextInt(10));
+ }
+
+ return builder.toString();
+ }
+}