diff --git a/README.md b/README.md
index 98cbe65..aefa02a 100755
--- a/README.md
+++ b/README.md
@@ -83,18 +83,13 @@ I2P router launched.
Press Ctrl-C to gracefully shut down the router (or send the SIGINT signal to the process).
```
-## Check that the I2P router is running and that it is listening for SAM connections
-
-`fuser 7656/tcp`
-
-
## Tunnel control
Note that it may take a short while for new tunnels to be set up.
Call the `dist/linux/router/bin/tunnel-control.sh` script as follows to create and destroy tunnels:
-#### Get the router reachability status. Returns a string such as "Testing", "Tirewalled", "Running", "Error"
+#### Get the router reachability status. Returns a string such as "Testing", "Firewalled", "Running", "Error"
`tunnel-control.sh router.reachability`
@@ -113,6 +108,7 @@ specified host and port. Note that the base 32 I2P destination address determini
`tunnel-control.sh server.state `
`tunnel-control.sh client.state `
+`tunnel-control.sh http.state `
`tunnel-control.sh socks.state `
@@ -130,6 +126,14 @@ specified host and port. Note that the base 32 I2P destination address determini
`tunnel-control.sh client.destroy `
+#### Create an http proxy (for accessing .i2p web sites), listening on the specified port
+
+`tunnel-control.sh http.create `
+
+#### Destroy the http proxy listening on the specified port
+
+`tunnel-control.sh http.destroy `
+
#### Create a socks tunnel, listening on the specified port
`tunnel-control.sh socks.create `
diff --git a/bin/build-all.sh b/bin/build-all.sh
index 8ac98da..10b7252 100755
--- a/bin/build-all.sh
+++ b/bin/build-all.sh
@@ -6,6 +6,8 @@ else
basedir=$(dirname $(dirname $(readlink -fm $0)))
fi
+rm -fr "$basedir/target" "$basedir/dist"
+
# retrieve the I2P Java sources, OpenJDK and the Ant build tool
"$basedir"/bin/import-packages.sh
diff --git a/bin/build-launcher.sh b/bin/build-launcher.sh
index ee88b9e..ab5aa9a 100755
--- a/bin/build-launcher.sh
+++ b/bin/build-launcher.sh
@@ -8,21 +8,23 @@ fi
source "$basedir/bin/java-config.sh"
-rm -fr target/org.getmonero.i2p.zero/classes
-rm -fr target/org.getmonero.i2p.zero.gui/classes
-# compile the Main class that starts the I2P router and SAM listener
-echo "*** Compiling Main class"
-$JAVA_HOME/bin/javac --module-path import/lib -d target/org.getmonero.i2p.zero/classes $(find org.getmonero.i2p.zero/src -name '*.java')
-$JAVA_HOME/bin/javac --module-path import/lib:import/javafx-sdks/linux/javafx-sdk-$JAVAFX_VERSION/lib:target/org.getmonero.i2p.zero/classes -d target/org.getmonero.i2p.zero.gui/classes $(find org.getmonero.i2p.zero.gui/src -name '*.java')
-cp -r org.getmonero.i2p.zero.gui/src/* target/org.getmonero.i2p.zero.gui/classes
-find target -type f -name '*.java' -delete
+echo "*** Compiling CLI"
+$JAVA_HOME/bin/javac --module-path target/modules/combined.jar -d target/classes/org.getmonero.i2p.zero $(find org.getmonero.i2p.zero/src -name '*.java')
-# package as a modular jar
-echo "*** Packaging as a modular jar"
-$JAVA_HOME/bin/jar --create --file target/org.getmonero.i2p.zero.jar --main-class org.getmonero.i2p.zero.Main -C target/org.getmonero.i2p.zero/classes .
-$JAVA_HOME/bin/jar --create --file target/org.getmonero.i2p.zero.gui.jar --main-class org.getmonero.i2p.zero.gui.Gui -C target/org.getmonero.i2p.zero.gui/classes .
+echo "*** Packaging CLI as a modular jar"
+$JAVA_HOME/bin/jar --create --file target/org.getmonero.i2p.zero.jar --main-class org.getmonero.i2p.zero.Main -C target/classes/org.getmonero.i2p.zero .
+echo "*** Compiling GUI"
+$JAVA_HOME/bin/javac --module-path target/org.getmonero.i2p.zero.jar:target/modules/combined.jar:import/javafx-sdks/linux/javafx-sdk-$JAVAFX_VERSION/lib -d target/classes/org.getmonero.i2p.zero.gui $(find org.getmonero.i2p.zero.gui/src -name '*.java')
+
+cp -r org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/*.{css,png,fxml,ttf} target/classes/org.getmonero.i2p.zero.gui/org/getmonero/i2p/zero/gui/
+
+echo "*** Packaging GUI as a modular jar"
+$JAVA_HOME/bin/jar --create --file target/org.getmonero.i2p.zero.gui.jar --main-class org.getmonero.i2p.zero.gui.Gui -C target/classes/org.getmonero.i2p.zero.gui .
+
+
+ hh
rm -fr "$basedir/dist"
for i in linux mac win linux-gui mac-gui win-gui; do mkdir -p "$basedir/dist/$i"; done
@@ -39,8 +41,8 @@ for i in linux mac win; do
JAVA_HOME_VARIANT=${JAVA_HOME_WIN} ;;
esac
echo "Using JAVA_HOME_VARIANT: $JAVA_HOME_VARIANT"
- "$JAVA_HOME"/bin/jlink --module-path "${JAVA_HOME_VARIANT}/jmods":target/modules:target/org.getmonero.i2p.zero.jar --add-modules org.getmonero.i2p.zero --output dist/$i/router --compress 2 --no-header-files --no-man-pages
- "$JAVA_HOME"/bin/jlink --module-path "${JAVA_HOME_VARIANT}/jmods":import/javafx-jmods/$i/javafx-jmods-${JAVAFX_VERSION}:target/modules:target/org.getmonero.i2p.zero.jar:target/org.getmonero.i2p.zero.gui.jar --add-modules org.getmonero.i2p.zero,org.getmonero.i2p.zero.gui,javafx.controls,javafx.fxml,java.desktop --output dist/$i-gui/router --compress 2 --no-header-files --no-man-pages
+ "$JAVA_HOME"/bin/jlink --module-path "${JAVA_HOME_VARIANT}/jmods":target/modules:target/org.getmonero.i2p.zero.jar --add-modules combined,org.getmonero.i2p.zero --output dist/$i/router --compress 2 --no-header-files --no-man-pages
+ "$JAVA_HOME"/bin/jlink --module-path "${JAVA_HOME_VARIANT}/jmods":import/javafx-jmods/$i/javafx-jmods-${JAVAFX_VERSION}:target/modules:target/org.getmonero.i2p.zero.jar:target/org.getmonero.i2p.zero.gui.jar --add-modules combined,org.getmonero.i2p.zero,org.getmonero.i2p.zero.gui,javafx.controls,javafx.fxml,java.desktop --output dist/$i-gui/router --compress 2 --no-header-files --no-man-pages
done
for i in linux mac linux-gui mac-gui; do
diff --git a/bin/convert-jars-to-modules.sh b/bin/convert-jars-to-modules.sh
index 2efc925..b87e1b0 100755
--- a/bin/convert-jars-to-modules.sh
+++ b/bin/convert-jars-to-modules.sh
@@ -8,20 +8,37 @@ fi
source "$basedir/bin/java-config.sh"
+cp "$basedir"/import/jetty-lib/*.jar "$basedir/import/lib/"
+
+rm -fr "$basedir/target/lib-combined"
+rm -fr "$basedir/target/lib-combined-tmp"
+mkdir -p "$basedir/target/lib-combined"
+mkdir -p "$basedir/target/lib-combined-tmp"
+
jarPaths=`find "$basedir/import/lib" -name '*.jar'`
+combinedJarPath="$basedir/target/lib-combined/combined.jar"
+for jarPath in $jarPaths; do unzip -quo $jarPath -d "$basedir/target/lib-combined-tmp"; done
+jar cf "$combinedJarPath" -C "$basedir/target/lib-combined-tmp" .
+rm -fr "$basedir/target/module-info"
+mkdir -p "$basedir/target/module-info"
+rm -fr "$basedir/target/modules"
mkdir -p "$basedir/target/modules"
-rm -f "$basedir/target/modules"/*
-
-for jarPath in $jarPaths; do
- moduleName=$(basename "${jarPath%.*}")
- echo "*** Determining dependencies for $moduleName"
- "$JAVA_HOME"/bin/jdeps --module-path "$basedir/import/lib" --add-modules=ALL-MODULE-PATH --generate-module-info "$basedir/target/module-info" "$jarPath"
-done
-for jarPath in $jarPaths; do
- moduleName=$(basename "${jarPath%.*}")
- echo "*** Creating new modular jar for $moduleName"
- "$JAVA_HOME"/bin/javac --module-path "$basedir/import/lib" --patch-module $moduleName=$jarPath $basedir/target/module-info/$moduleName/module-info.java
- cp $jarPath "$basedir/target/modules/"
- "$JAVA_HOME"/bin/jar uf "$basedir/target/modules/${moduleName}.jar" -C "$basedir/target/module-info/$moduleName" module-info.class
-done
+
+echo "*** Determining dependencies for $combinedJarPath"
+"$JAVA_HOME"/bin/jdeps --add-modules=ALL-MODULE-PATH --generate-module-info "$basedir/target/module-info" "$combinedJarPath"
+
+if [ $(uname -s) = Darwin ]; then
+ sed -i '' -e '$ d' "$basedir/target/module-info/combined/module-info.java"
+else
+ sed -i '$ d' "$basedir/target/module-info/combined/module-info.java"
+fi
+echo 'uses org.eclipse.jetty.http.HttpFieldPreEncoder; }' >> "$basedir/target/module-info/combined/module-info.java"
+
+
+echo "*** Creating new combined modular jar"
+"$JAVA_HOME"/bin/javac --module-path "$combinedJarPath/combined" --patch-module combined=$combinedJarPath $basedir/target/module-info/combined/module-info.java
+cp $combinedJarPath "$basedir/target/modules/"
+"$JAVA_HOME"/bin/jar uf "$basedir/target/modules/combined.jar" -C "$basedir/target/module-info/combined" module-info.class
+
+
diff --git a/bin/import-packages.sh b/bin/import-packages.sh
index 3cc24a9..9c8e843 100755
--- a/bin/import-packages.sh
+++ b/bin/import-packages.sh
@@ -37,6 +37,18 @@ if [ ! -d "$basedir/import/apache-ant-1.10.5" ]; then
tar zxvf apache-ant-1.10.5-bin.tar.gz
fi
+if [ ! -d "$basedir/import/jetty-lib" ]; then
+ mkdir -p jetty-lib
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/eclipse/jetty/jetty-server/9.4.14.v20181114/jetty-server-9.4.14.v20181114.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/eclipse/jetty/jetty-util/9.4.14.v20181114/jetty-util-9.4.14.v20181114.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/eclipse/jetty/jetty-http/9.4.14.v20181114/jetty-http-9.4.14.v20181114.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/eclipse/jetty/jetty-io/9.4.14.v20181114/jetty-io-9.4.14.v20181114.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/slf4j/slf4j-simple/1.7.25/slf4j-simple-1.7.25.jar
+ wget --directory-prefix=jetty-lib http://central.maven.org/maven2/org/eclipse/jetty/jetty-jmx/9.4.14.v20181114/jetty-jmx-9.4.14.v20181114.jar
+fi
+
if [ ! -d "$basedir/import/javafx-sdks" ]; then
mkdir -p javafx-sdks
mkdir -p javafx-sdks/linux javafx-sdks/mac javafx-sdks/win
diff --git a/org.getmonero.i2p.zero.gui/org.getmonero.i2p.zero.gui.iml b/org.getmonero.i2p.zero.gui/org.getmonero.i2p.zero.gui.iml
index a42f527..ceefdf6 100644
--- a/org.getmonero.i2p.zero.gui/org.getmonero.i2p.zero.gui.iml
+++ b/org.getmonero.i2p.zero.gui/org.getmonero.i2p.zero.gui.iml
@@ -7,11 +7,10 @@
-
-
+
@@ -20,7 +19,7 @@
-
+
@@ -29,7 +28,7 @@
-
+
@@ -38,7 +37,7 @@
-
+
@@ -47,7 +46,7 @@
-
+
@@ -56,7 +55,7 @@
-
+
@@ -65,7 +64,7 @@
-
+
@@ -74,11 +73,12 @@
-
+
+
\ No newline at end of file
diff --git a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/AddTunnelController.java b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/AddTunnelController.java
index fa0ff46..0e5c0f8 100644
--- a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/AddTunnelController.java
+++ b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/AddTunnelController.java
@@ -12,12 +12,14 @@ public class AddTunnelController {
@FXML Pane clientTunnelConfigPane;
@FXML Pane serverTunnelConfigPane;
+ @FXML Pane httpProxyConfigPane;
@FXML Pane socksProxyConfigPane;
@FXML Button addButton;
@FXML Button cancelButton;
@FXML ToggleGroup tunnelType;
@FXML RadioButton clientTunnelRadioButton;
@FXML RadioButton serverTunnelRadioButton;
+ @FXML RadioButton httpProxyRadioButton;
@FXML RadioButton socksProxyRadioButton;
@FXML TextField clientDestAddrField;
@FXML TextField clientPortField;
@@ -26,6 +28,7 @@ public class AddTunnelController {
@FXML TextField serverKeyField;
@FXML TextField serverAddrField;
@FXML TextField socksPortField;
+ @FXML TextField httpProxyPortField;
private void updateAddButtonState() {
@@ -38,6 +41,9 @@ public class AddTunnelController {
else if(tunnelType.getSelectedToggle().equals(socksProxyRadioButton)) {
addButton.setDisable(Stream.of(socksPortField).anyMatch(f->f.getText().isBlank()));
}
+ else if(tunnelType.getSelectedToggle().equals(httpProxyRadioButton)) {
+ addButton.setDisable(Stream.of(httpProxyPortField).anyMatch(f->f.getText().isBlank()));
+ }
}
@FXML
@@ -45,6 +51,7 @@ public class AddTunnelController {
serverTunnelConfigPane.setVisible(false);
socksProxyConfigPane.setVisible(false);
+ httpProxyConfigPane.setVisible(false);
addButton.setOnAction(ev->{
try {
@@ -52,13 +59,16 @@ public class AddTunnelController {
var tunnelControl = controller.getRouterWrapper().getTunnelControl();
var tunnelList = tunnelControl.getTunnelList();
if (tunnelType.getSelectedToggle().equals(clientTunnelRadioButton)) {
- Tunnel t = new TunnelControl.ClientTunnel(clientDestAddrField.getText(), Integer.parseInt(clientPortField.getText()));
+ Tunnel t = new TunnelControl.ClientTunnel(clientDestAddrField.getText(), Integer.parseInt(clientPortField.getText())).start();
tunnelList.addTunnel(t);
} else if (tunnelType.getSelectedToggle().equals(serverTunnelRadioButton)) {
- Tunnel t = new TunnelControl.ServerTunnel(serverHostField.getText(), Integer.parseInt(serverPortField.getText()), new TunnelControl.KeyPair(serverKeyField.getText()), tunnelControl.getTunnelControlTempDir());
+ Tunnel t = new TunnelControl.ServerTunnel(serverHostField.getText(), Integer.parseInt(serverPortField.getText()), new TunnelControl.KeyPair(serverKeyField.getText()), tunnelControl.getTunnelControlTempDir()).start();
tunnelList.addTunnel(t);
} else if (tunnelType.getSelectedToggle().equals(socksProxyRadioButton)) {
- Tunnel t = new TunnelControl.SocksTunnel(Integer.parseInt(socksPortField.getText()));
+ Tunnel t = new TunnelControl.SocksTunnel(Integer.parseInt(socksPortField.getText())).start();
+ tunnelList.addTunnel(t);
+ } else if (tunnelType.getSelectedToggle().equals(httpProxyRadioButton)) {
+ Tunnel t = new TunnelControl.HttpClientTunnel(Integer.parseInt(httpProxyPortField.getText())).start();
tunnelList.addTunnel(t);
}
clientTunnelConfigPane.getScene().getWindow().hide();
@@ -80,17 +90,18 @@ public class AddTunnelController {
tunnelType.selectedToggleProperty().addListener((ov, oldToggle, newToggle)-> {
try {
- var tunnelControl = Gui.instance.getController().getRouterWrapper().getTunnelControl();
clientTunnelConfigPane.setVisible(false);
serverTunnelConfigPane.setVisible(false);
+ httpProxyConfigPane.setVisible(false);
socksProxyConfigPane.setVisible(false);
if (newToggle.equals(clientTunnelRadioButton)) clientTunnelConfigPane.setVisible(true);
if (newToggle.equals(serverTunnelRadioButton)) {
var keyPair = TunnelControl.KeyPair.gen();
- serverKeyField.setText(keyPair.seckey + "," + keyPair.pubkey);
+ serverKeyField.setText(keyPair.toString());
serverAddrField.setText(keyPair.b32Dest);
serverTunnelConfigPane.setVisible(true);
}
+ if (newToggle.equals(httpProxyRadioButton)) httpProxyConfigPane.setVisible(true);
if (newToggle.equals(socksProxyRadioButton)) socksProxyConfigPane.setVisible(true);
updateAddButtonState();
}
@@ -106,13 +117,11 @@ public class AddTunnelController {
String key = newValue;
if(key!=null && !key.isEmpty()) {
try {
- TunnelControl.KeyPair keyPair = new TunnelControl.KeyPair(key);
- serverAddrField.setText(keyPair.b32Dest);
+ serverAddrField.setText(new TunnelControl.KeyPair(key).b32Dest);
}
catch (Exception e) {
// ignore exception. user may be part way through entering string
}
-
}
});
diff --git a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Controller.java b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Controller.java
index 19c13ce..10d48f5 100644
--- a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Controller.java
+++ b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Controller.java
@@ -15,27 +15,32 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
+import javafx.stage.DirectoryChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.getmonero.i2p.zero.RouterWrapper;
-import static org.getmonero.i2p.zero.TunnelControl.Tunnel;
+import org.getmonero.i2p.zero.TunnelControl;
+import static org.getmonero.i2p.zero.TunnelControl.*;
+
+import java.io.File;
import java.text.DecimalFormat;
-import java.util.List;
+import java.util.Optional;
import java.util.Properties;
+import java.util.stream.Stream;
public class Controller {
private RouterWrapper routerWrapper;
- @FXML
- private BorderPane rootBorderPane;
+ @FXML private BorderPane rootBorderPane;
@FXML private Slider bandwidthSlider;
@FXML private Label maxBandwidthLabel;
@FXML private ImageView masterToggle;
@FXML private AnchorPane bandwidthDisabledOverlay;
@FXML private Tab bandwidthTab;
@FXML private Tab tunnelsTab;
+ @FXML private Tab eepSiteTab;
@FXML private Tab helpTab;
@FXML private Label statusLabel;
@FXML private Button tunnelAddButton;
@@ -54,17 +59,32 @@ public class Controller {
@FXML private Label bandwidthOut5m;
@FXML private Label bandwidthOutAll;
@FXML private Label totalTransferredOut;
+ @FXML private CheckBox eepSiteEnableCheckbox;
+ @FXML private TextField eepSiteAddrField;
+ @FXML private TextField eepSiteSecretKeyField;
+ @FXML private Button eepSiteGenButton;
+ @FXML private TextField eepSiteContentDirField;
+ @FXML private Button eepSiteContentDirChooseButton;
+ @FXML private TextField eepSiteLogsDirField;
+ @FXML private Button eepSiteLogsDirChooseButton;
+ @FXML private CheckBox eepSiteEnableLogsCheckbox;
+ @FXML private CheckBox eepSiteAllowDirBrowsingCheckbox;
+ @FXML private TextField eepSiteLocalPortField;
+
DecimalFormat format2dp = new DecimalFormat("0.00");
private boolean masterState = true;
private final ObservableList tunnelTableList = FXCollections.observableArrayList();
-
+ private boolean eepSiteTabInitialized = false;
+
private Stage getStage() {
return (Stage) rootBorderPane.getScene().getWindow();
}
@FXML private void initialize() {
+ DirectoryChooser directoryChooser = new DirectoryChooser();
+
typeCol.setCellValueFactory(new PropertyValueFactory("type"));
stateCol.setCellValueFactory(new PropertyValueFactory("state"));
hostCol.setCellValueFactory(new PropertyValueFactory("host"));
@@ -115,12 +135,99 @@ public class Controller {
stage.setHeight(370);
}
else if(tunnelsTab.isSelected()) {
- stage.setWidth(900);
+ stage.setWidth(830);
+ }
+ else if(eepSiteTab.isSelected()) {
+ stage.setWidth(830);
+ stage.setHeight(500);
+
+ if(!eepSiteTabInitialized) {
+ EepSiteTunnel eepSiteTunnel = getEepSiteTunnel();
+ eepSiteSecretKeyField.setText(eepSiteTunnel.keyPair.toString());
+ eepSiteAddrField.setText("http://" + eepSiteTunnel.keyPair.b32Dest);
+ eepSiteContentDirField.setText(eepSiteTunnel.contentDir);
+ eepSiteLogsDirField.setText(eepSiteTunnel.logsDir);
+ eepSiteEnableCheckbox.setSelected(eepSiteTunnel.enabled);
+ eepSiteEnableLogsCheckbox.setSelected(eepSiteTunnel.enableLogs);
+ eepSiteAllowDirBrowsingCheckbox.setSelected(eepSiteTunnel.allowDirectoryBrowsing);
+ eepSiteLocalPortField.setText(eepSiteTunnel.port + "");
+ eepSiteTabInitialized = true;
+
+ // modifying eepSiteSecretKeyField/eepSiteLocalPortField will require the eepsite tunnel to be destroyed
+ // and later recreated whenever the user is finished editing settings and ticks the enabled box again
+ eepSiteSecretKeyField.textProperty().addListener((observable, oldValue, newValue) -> {
+ eepSiteAddrField.setText("");
+ String key = newValue;
+ if(key!=null && !key.isEmpty()) {
+ try {
+ eepSiteAddrField.setText("http://" + new TunnelControl.KeyPair(key).b32Dest);
+ }
+ catch (Exception e2) {
+ // ignore exception. user may be part way through entering string
+ }
+ eepSiteEnableCheckbox.setSelected(false);
+ }
+ });
+ eepSiteGenButton.setOnAction(ev->{
+ getEepSiteTunnel().keyPair = KeyPair.gen();
+ eepSiteSecretKeyField.setText(getEepSiteTunnel().keyPair.toString());
+ });
+ eepSiteLocalPortField.textProperty().addListener((ov, oldValue, newValue)->{
+ eepSiteEnableCheckbox.setSelected(false);
+ getEepSiteTunnel().port = Integer.parseInt(newValue);
+ save();
+ eepSiteEnableCheckbox.setSelected(false);
+ });
+
+ eepSiteEnableCheckbox.selectedProperty().addListener((ov, oldValue, newValue)->{
+ getEepSiteTunnel().enabled = newValue;
+ if(oldValue!=newValue) {
+ save();
+ getRouterWrapper().getTunnelControl().getTunnelList().fireChangeEvent();
+ if(getEepSiteTunnel().enabled) {
+ getEepSiteTunnel().start();
+ }
+ else {
+ getEepSiteTunnel().destroy();
+ }
+ }
+ });
+
+
+ // changing eepSiteContentDirChooseButton/eepSiteLogsDirChooseButton/eepSiteEnableLogsCheckbox/eepSiteAllowDirBrowsingCheckbox only requires a jetty restart
+ eepSiteContentDirChooseButton.setOnAction(ev->{
+ File selectedDirectory = directoryChooser.showDialog(getStage());
+ if (selectedDirectory!=null) {
+ eepSiteContentDirField.setText(selectedDirectory.getAbsolutePath());
+ getEepSiteTunnel().contentDir = selectedDirectory.getAbsolutePath();
+ save();
+ if(getEepSiteTunnel().enabled) restartJetty();
+ }
+ });
+ eepSiteLogsDirChooseButton.setOnAction(ev->{
+ File selectedDirectory = directoryChooser.showDialog(getStage());
+ if (selectedDirectory!=null) {
+ eepSiteLogsDirField.setText(selectedDirectory.getAbsolutePath());
+ getEepSiteTunnel().logsDir = selectedDirectory.getAbsolutePath();
+ save();
+ if(getEepSiteTunnel().enabled) restartJetty();
+ }
+ });
+ eepSiteEnableLogsCheckbox.selectedProperty().addListener((ov, oldValue, newValue)->{
+ getEepSiteTunnel().enableLogs = newValue;
+ save();
+ if(getEepSiteTunnel().enabled) restartJetty();
+ });
+ eepSiteAllowDirBrowsingCheckbox.selectedProperty().addListener((ov, oldValue, newValue)->{
+ getEepSiteTunnel().allowDirectoryBrowsing = newValue;
+ save();
+ if(getEepSiteTunnel().enabled) restartJetty();
+ });
+
+ }
}
};
- bandwidthTab.setOnSelectionChanged(tabSelectionEventHandler);
- tunnelsTab.setOnSelectionChanged(tabSelectionEventHandler);
- helpTab.setOnSelectionChanged(tabSelectionEventHandler);
+ Stream.of(bandwidthTab, tunnelsTab, eepSiteTab, helpTab).forEach(tab->tab.setOnSelectionChanged(tabSelectionEventHandler));
bandwidthSlider.valueProperty().addListener((observableValue, oldValue, newValue)-> {
maxBandwidthLabel.setText(String.format("%.1f", newValue.floatValue()) + " Mbps");
@@ -155,7 +262,7 @@ public class Controller {
var tunnelList = getRouterWrapper().getTunnelControl().getTunnelList();
tunnelList.addChangeListener(tunnels->{
tunnelTableList.clear();
- tunnelTableList.addAll(tunnels);
+ tunnels.stream().filter(Tunnel::getEnabled).forEach(tunnelTableList::add);
});
}).start();
@@ -184,8 +291,6 @@ public class Controller {
});
bandwidthUpdateThread.start();
- Runtime.getRuntime().addShutdownHook(new Thread(()->bandwidthUpdateThread.interrupt()));
-
}
public RouterWrapper getRouterWrapper() {
@@ -210,5 +315,18 @@ public class Controller {
}
+ private void restartJetty() {
+ Optional eepSiteTunnelOptional = getRouterWrapper().getTunnelControl().getTunnelList().getTunnelsCopyStream().filter(t->t.getType().equals("eepsite")).findFirst();
+ EepSiteTunnel eepSiteTunnel = (EepSiteTunnel) eepSiteTunnelOptional.get();
+ eepSiteTunnel.stopJetty();
+ new Thread(()->eepSiteTunnel.startJetty()).start();
+ }
+ private void save() {
+ getRouterWrapper().getTunnelControl().getTunnelList().save();
+ }
+ private EepSiteTunnel getEepSiteTunnel() {
+ return getRouterWrapper().getTunnelControl().getEepSiteTunnel();
+ }
+
}
diff --git a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Gui.java b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Gui.java
index 389d4b0..bdd08f1 100644
--- a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Gui.java
+++ b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/Gui.java
@@ -7,8 +7,10 @@ import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
+import javafx.scene.control.Alert;
import javafx.scene.image.Image;
import javafx.stage.Stage;
+import org.getmonero.i2p.zero.TunnelControl;
import javax.imageio.ImageIO;
@@ -22,6 +24,15 @@ public class Gui extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
+ if(TunnelControl.isPortInUse()) {
+ Alert alert = new Alert(Alert.AlertType.ERROR);
+ alert.setTitle("Error");
+ alert.setHeaderText(null);
+ alert.setContentText("I2P-zero is already running");
+ alert.showAndWait();
+ System.exit(1);
+ }
+
instance = this;
String osName = System.getProperty("os.name");
if(osName.startsWith("Mac")) {
@@ -36,6 +47,8 @@ public class Gui extends Application {
controller = loader.getController();
primaryStage.setTitle("I2P-zero");
+ primaryStage.setWidth(360);
+ primaryStage.setHeight(340);
primaryStage.setMinWidth(360);
primaryStage.setMinHeight(370);
Scene scene = new Scene(root);
diff --git a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/addTunnel.fxml b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/addTunnel.fxml
index 23aa442..cd1f017 100644
--- a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/addTunnel.fxml
+++ b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/addTunnel.fxml
@@ -8,7 +8,7 @@
-
+
@@ -18,10 +18,10 @@
-
-
-
-
+
+
+
+
@@ -29,7 +29,7 @@
-
+
@@ -41,11 +41,18 @@
-
+
+
+
+
+
+
+
+
diff --git a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/gui.fxml b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/gui.fxml
index 554ad37..2119600 100644
--- a/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/gui.fxml
+++ b/org.getmonero.i2p.zero.gui/src/org/getmonero/i2p/zero/gui/gui.fxml
@@ -2,6 +2,7 @@
+
@@ -9,6 +10,7 @@
+
@@ -16,7 +18,7 @@
-
+
@@ -113,11 +115,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-