A lot of refactor work and housekeeping

- simplified a lot of code
- updated naming to be consistent across project
- added FXML annotations
This commit is contained in:
dorving 2023-05-05 20:53:30 +02:00
parent 850e89eb5e
commit 5186e2526b
33 changed files with 1246 additions and 1292 deletions

View File

@ -1,12 +1,17 @@
package gearth.misc; package gearth.misc;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.ObjectBinding; import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import java.util.function.Function;
/** /**
* Provides utility methods for bindings. * Provides utility methods for bindings.
* *
@ -14,6 +19,27 @@ import javafx.util.StringConverter;
*/ */
public final class BindingsUtil { public final class BindingsUtil {
/**
* Creates a binding that is true if the function returns true for the applied string.
*/
public static BooleanBinding stringMatches(ObservableValue<String> stringValue, Function<String, Boolean> function) {
return Bindings.createBooleanBinding(() -> function.apply(stringValue.getValue()), stringValue);
}
/**
* Creates a binding that is true if the string is an integer.
*/
public static BooleanBinding isInteger(ObservableValue<String> stringValue) {
return stringMatches(stringValue, StringUtils::isInteger);
}
/**
* Creates a binding that is true if the string is an UShort.
*/
public static BooleanBinding isUShort(ObservableValue<String> stringValue) {
return stringMatches(stringValue, StringUtils::isUShort);
}
/** /**
* Ensures the list always contains the value of the binding. * Ensures the list always contains the value of the binding.
*/ */
@ -25,6 +51,20 @@ public final class BindingsUtil {
list.add(binding.get()); list.add(binding.get());
} }
/**
* Sets the value of a property and binds it to another observable value.
*/
public static<T> void setAndBind(Property<T> a, ObservableValue<T> b, boolean unbindPrevious) {
if (unbindPrevious)
a.unbind();
a.setValue(b.getValue());
a.bind(b);
}
public static<T> void setAndBind(Property<T> a, ObservableValue<T> b) {
setAndBind(a, b, false);
}
/** /**
* Sets the value of a property and binds it bidirectionally to another property. * Sets the value of a property and binds it bidirectionally to another property.
*/ */

View File

@ -0,0 +1,17 @@
package gearth.misc;
import gearth.GEarth;
import javafx.event.ActionEvent;
import javafx.scene.control.Hyperlink;
public final class HyperLinkUtil {
public static void showDocumentOnClick(Hyperlink link) {
link.setOnAction((ActionEvent event) -> {
final Hyperlink hyperlink = (Hyperlink) event.getTarget();
final String url = hyperlink.getTooltip().getText();
GEarth.main.getHostServices().showDocument(url);
event.consume();
});
}
}

View File

@ -0,0 +1,29 @@
package gearth.misc;
public final class StringUtils {
public static boolean isInteger(String string) {
try {
Integer.parseInt(string);
return true;
}
catch (NumberFormatException e){
return false;
}
}
public static boolean isUShort(String string) {
try {
int res = Integer.parseInt(string);
return res >= 0 && res < (256 * 256);
} catch (NumberFormatException e) {
return false;
}
}
public static String cleanTextContent(String text)
{
text = text.replaceAll("\\p{Cntrl}&&[^\n\t]", "");
return text.trim();
}
}

View File

@ -1,6 +1,6 @@
package gearth.services.scheduler; package gearth.services.scheduler;
import gearth.ui.subforms.scheduler.SchedulerController; import gearth.misc.StringUtils;
/** /**
* Created by Jonas on 11/04/18. * Created by Jonas on 11/04/18.
@ -23,7 +23,7 @@ public class Interval {
offset = -1; offset = -1;
return; return;
} }
if (!SchedulerController.stringIsNumber(split[0]) || (split.length == 2 && !SchedulerController.stringIsNumber(split[1]))) { if (!StringUtils.isInteger(split[0]) || (split.length == 2 && !StringUtils.isInteger(split[1]))) {
delay = -1; delay = -1;
offset = -1; offset = -1;
return; return;

View File

@ -1,31 +1,41 @@
package gearth.ui.buttons; package gearth.ui.buttons;
import javafx.event.EventHandler;
import javafx.scene.Cursor; import javafx.scene.Cursor;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import java.io.File; import java.util.Objects;
public class BoxButton extends StackPane { public class BoxButton extends StackPane {
private ImageView imageView; private final ImageView imageView;
private Image image; private final Image image;
private Image imageOnHover; private final Image imageOnHover;
private boolean isVisible; private boolean isVisible;
//paths zijn relatief aan deze classpath /**
* Creates a new box button.
*
* @param imageName name of the image file in src/main/java/gearth/ui/buttons/files/
* @param imageOnHoverName name of the image file in src/main/java/gearth/ui/buttons/files/
*/
public BoxButton(String imageName, String imageOnHoverName) { public BoxButton(String imageName, String imageOnHoverName) {
this.image = new Image(getClass().getResourceAsStream("files/" + imageName)); this.image = getImageResource(imageName);
this.imageOnHover = new Image(getClass().getResourceAsStream("files/" + imageOnHoverName)); this.imageOnHover = getImageResource(imageOnHoverName);
this.imageView = new ImageView(); this.imageView = new ImageView();
setCursor(Cursor.DEFAULT); setCursor(Cursor.DEFAULT);
getChildren().add(imageView); getChildren().add(imageView);
setOnMouseEntered(onMouseHover); setOnMouseEntered(t -> {
setOnMouseExited(onMouseHoverDone); if (isVisible) imageView.setImage(imageOnHover);
});
setOnMouseExited(t -> {
if (isVisible) imageView.setImage(image);
});
}
private Image getImageResource(String imageName) {
return new Image(Objects.requireNonNull(getClass().getResourceAsStream("files/" + imageName)));
} }
public void show() { public void show() {
@ -37,19 +47,4 @@ public class BoxButton extends StackPane {
imageView.setImage(null); imageView.setImage(null);
isVisible = false; isVisible = false;
} }
private EventHandler<MouseEvent> onMouseHover =
t -> {
if (isVisible) {
imageView.setImage(imageOnHover);
}
};
private EventHandler<MouseEvent> onMouseHoverDone =
t -> {
if (isVisible) {
imageView.setImage(image);
}
};
} }

View File

@ -4,6 +4,7 @@ package gearth.ui.buttons;
* Created by Jonas on 26/09/18. * Created by Jonas on 26/09/18.
*/ */
public class ExitButton extends BoxButton { public class ExitButton extends BoxButton {
public ExitButton() { public ExitButton() {
super("ButtonExit.png", "ButtonExitHover.png"); super("ButtonExit.png", "ButtonExitHover.png");
} }

View File

@ -4,6 +4,7 @@ package gearth.ui.buttons;
* Created by Jonas on 26/09/18. * Created by Jonas on 26/09/18.
*/ */
public class FireButton extends BoxButton { public class FireButton extends BoxButton {
public FireButton() { public FireButton() {
super("ButtonFire.png", "ButtonFireHover.png"); super("ButtonFire.png", "ButtonFireHover.png");
} }

View File

@ -10,45 +10,55 @@ import javafx.scene.layout.StackPane;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Created by Jonas on 11/04/18. * Created by Jonas on 11/04/18.
*/ */
public class PauseResumeButton extends StackPane{ public class PauseResumeButton extends StackPane{
private boolean isPaused[] = {false}; private final boolean[] isPaused = {false};
private final ImageView imageView;
private final Image imagePause;
private final Image imagePauseOnHover;
private ImageView imageView; private final Image imageResume;
private Image imagePause; private final Image imageResumeOnHover;
private Image imagePauseOnHover;
private Image imageResume;
private Image imageResumeOnHover;
private volatile boolean isHovering = false; private volatile boolean isHovering = false;
private List<InvalidationListener> clickListeners = new ArrayList<>(); private final List<InvalidationListener> clickListeners = new ArrayList<>();
public PauseResumeButton(boolean isPaused) { public PauseResumeButton(boolean isPaused) {
this.isPaused[0] = isPaused; this.isPaused[0] = isPaused;
this.imagePause = new Image(getClass().getResourceAsStream("files/ButtonPause.png")); this.imagePause = getImageResource("files/ButtonPause.png");
this.imagePauseOnHover = new Image(getClass().getResourceAsStream("files/ButtonPauseHover.png")); this.imagePauseOnHover = getImageResource("files/ButtonPauseHover.png");
this.imageResume = new Image(getClass().getResourceAsStream("files/ButtonResume.png")); this.imageResume = getImageResource("files/ButtonResume.png");
this.imageResumeOnHover = new Image(getClass().getResourceAsStream("files/ButtonResumeHover.png")); this.imageResumeOnHover = getImageResource("files/ButtonResumeHover.png");
this.imageView = new ImageView(); this.imageView = new ImageView();
setCursor(Cursor.DEFAULT); setCursor(Cursor.DEFAULT);
getChildren().add(imageView); getChildren().add(imageView);
setOnMouseEntered(onMouseHover); setOnMouseEntered( t -> {
setOnMouseExited(onMouseHoverDone); imageView.setImage(isPaused() ? imageResumeOnHover : imagePauseOnHover);
isHovering = true;
});
setOnMouseExited(t -> {
imageView.setImage(isPaused() ? imageResume : imagePause);
isHovering = false;
});
imageView.setImage(isPaused() ? imageResume : imagePause); imageView.setImage(isPaused() ? imageResume : imagePause);
setEventHandler(MouseEvent.MOUSE_CLICKED, event -> click()); setEventHandler(MouseEvent.MOUSE_CLICKED, event -> click());
} }
private Image getImageResource(String name) {
return new Image(Objects.requireNonNull(getClass().getResourceAsStream(name)));
}
public boolean isPaused() { public boolean isPaused() {
return isPaused[0]; return isPaused[0];
} }
@ -57,24 +67,8 @@ public class PauseResumeButton extends StackPane{
clickListeners.add(listener); clickListeners.add(listener);
} }
private EventHandler<MouseEvent> onMouseHover =
t -> {
imageView.setImage(isPaused() ? imageResumeOnHover : imagePauseOnHover);
isHovering = true;
};
private EventHandler<MouseEvent> onMouseHoverDone =
t -> {
imageView.setImage(isPaused() ? imageResume : imagePause);
isHovering = false;
};
public void setPaused(boolean paused) { public void setPaused(boolean paused) {
isPaused[0] = paused; isPaused[0] = paused;
imageView.setImage(isPaused() ? imageView.setImage(isPaused() ?
(isHovering ? imageResumeOnHover : imageResume) : (isHovering ? imageResumeOnHover : imageResume) :
(isHovering ? imagePauseOnHover : imagePause) (isHovering ? imagePauseOnHover : imagePause)
@ -86,22 +80,4 @@ public class PauseResumeButton extends StackPane{
clickListeners.get(i).invalidated(null); clickListeners.get(i).invalidated(null);
} }
} }
// private ImageView imageView;
// private Image image;
// private Image imageOnHover;
// private boolean isVisible;
//
// //paths zijn relatief aan deze classpath
// public BoxButton(String imagePath, String imageOnHoverPath) {
// this.image = new Image(getClass().getResourceAsStream(imagePath));
// this.imageOnHover = new Image(getClass().getResourceAsStream(imageOnHoverPath));
// this.imageView = new ImageView();
//
// setCursor(Cursor.DEFAULT);
// getChildren().add(imageView);
// setOnMouseEntered(onMouseHover);
// setOnMouseExited(onMouseHoverDone);
// }
} }

View File

@ -4,6 +4,8 @@ package gearth.ui.buttons;
* Created by Jonas on 26/09/18. * Created by Jonas on 26/09/18.
*/ */
public class ReloadButton extends BoxButton { public class ReloadButton extends BoxButton {
public ReloadButton() { public ReloadButton() {
super("ButtonReload.png", "ButtonReloadHover.png"); } super("ButtonReload.png", "ButtonReloadHover.png");
}
} }

View File

@ -8,65 +8,260 @@ import gearth.protocol.connection.HState;
import gearth.protocol.connection.proxy.ProxyProviderFactory; import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.services.Constants; import gearth.services.Constants;
import gearth.ui.GEarthProperties; import gearth.ui.GEarthProperties;
import gearth.ui.SubForm;
import gearth.ui.translations.TranslatableString; import gearth.ui.translations.TranslatableString;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.event.ActionEvent; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import gearth.ui.SubForm;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionController extends SubForm { public class ConnectionController extends SubForm {
public ComboBox<String> inpPort; public ComboBox<String> portOptionsBox;
public ComboBox<String> inpHost; public ComboBox<String> hostOptionsBox;
public Button btnConnect;
public Label lblInpPort, lblInpHost, lblPort, lblHost, lblHotelVersion, lblClient, lblStateHead, lblState;
public TextField outHost;
public TextField outPort;
public CheckBox cbx_autodetect;
public TextField txtfield_hotelversion;
private final Object lock = new Object(); public Button connectButton;
private volatile int fullyInitialized = 0; public Label
portOptionsLabel,
hostOptionsLabel,
connectedPortLabel,
connectedHostLabel,
connectedHotelVersionLabel,
selectedClientLabel,
connectionStateHeaderLabel,
notConnectedStateLabel;
public TextField connectedHostField;
public TextField connectedPortField;
public CheckBox autoDetectBox;
public TextField connectedHotelVersionField;
public ToggleGroup tgl_clientMode; public GridPane clientTypeSelectionGrid;
public RadioButton rd_unity; public ToggleGroup clientTypeOptions;
public RadioButton rd_flash; public RadioButton unityOption;
public RadioButton rd_nitro; public RadioButton flashOption;
public GridPane grd_clientSelection; public RadioButton nitroOption;
private volatile int initcount = 0; private final AtomicInteger initState = new AtomicInteger(0);
private final AtomicInteger initCount = new AtomicInteger(0);
private TranslatableString connect, state; private TranslatableString connect, state;
public void initialize() { public void initialize() {
Constants.UNITY_PACKETS = rd_unity.isSelected(); Constants.UNITY_PACKETS = unityOption.isSelected();
tgl_clientMode.selectedToggleProperty().addListener(observable -> { clientTypeOptions.selectedToggleProperty().addListener(observable -> {
changeClientMode(); changeClientMode();
Constants.UNITY_PACKETS = rd_unity.isSelected(); Constants.UNITY_PACKETS = unityOption.isSelected();
}); });
GEarthProperties.clientTypeProperty GEarthProperties.clientTypeProperty
.addListener((observable, oldValue, newValue) -> selectClientType(newValue)); .addListener((observable, oldValue, newValue) -> selectClientType(newValue));
selectClientType(GEarthProperties.clientTypeProperty.getValue()); selectClientType(GEarthProperties.clientTypeProperty.getValue());
cbx_autodetect.selectedProperty().addListener(observable -> updateInputUI()); autoDetectBox.selectedProperty().addListener(observable -> updateInputUI());
inpPort.getEditor().textProperty().addListener(observable -> updateInputUI()); portOptionsBox.getEditor().textProperty().addListener(observable -> updateInputUI());
BindingsUtil.setAndBindBiDirectional(cbx_autodetect.selectedProperty(), GEarthProperties.autoDetectProperty); BindingsUtil.setAndBindBiDirectional(autoDetectBox.selectedProperty(), GEarthProperties.autoDetectProperty);
BindingsUtil.setAndBindBiDirectional(outHost.textProperty(), GEarthProperties.hostProperty); BindingsUtil.setAndBindBiDirectional(connectedHostField.textProperty(), GEarthProperties.hostProperty);
BindingsUtil.setAndBindBiDirectional(outPort.textProperty(), GEarthProperties.portProperty); BindingsUtil.setAndBindBiDirectional(connectedPortField.textProperty(), GEarthProperties.portProperty);
List<String> knownHosts = ProxyProviderFactory.autoDetectHosts; initHostSelection();
Set<String> hosts = new HashSet<>();
Set<String> ports = new HashSet<>(); if (initState.incrementAndGet() == 2)
Platform.runLater(this::updateInputUI);
tryMaybeConnectOnInit();
initLanguageBinding();
}
@Override
public void onParentSet() {
if (initState.incrementAndGet() == 2)
Platform.runLater(this::updateInputUI);
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> Platform.runLater(() -> {
updateInputUI();
if (newValue == HState.NOT_CONNECTED) {
state.setKey(0, "tab.connection.state.notconnected");
connect.setKey(0, "tab.connection.button.connect");
connectedHostField.setText("");
connectedPortField.setText("");
} else if (oldValue == HState.NOT_CONNECTED)
connect.setKey(0, "tab.connection.button.abort");
if (newValue == HState.CONNECTED)
state.setKey(0, "tab.connection.state.connected");
if (newValue == HState.WAITING_FOR_CLIENT)
state.setKey(0, "tab.connection.state.waiting");
if (newValue == HState.CONNECTED && useFlash()) {
final String host = getHConnection().getDomain();
final int port = getHConnection().getServerPort();
connectedHostField.setText(host);
connectedPortField.setText(Integer.toString(port));
GEarthProperties.hostProperty.set(host);
GEarthProperties.portProperty.set(port);
}
}));
Platform.runLater(this::updateInputUI);
tryMaybeConnectOnInit();
}
@Override
protected void onExit() {
GEarthProperties.clientTypeProperty.set(
flashOption.isSelected() ? HClient.FLASH
: unityOption.isSelected() ? HClient.UNITY
: HClient.NITRO);
getHConnection().abort();
}
@FXML
public void onClickConnectButton() {
if (getHConnection().getState() == HState.NOT_CONNECTED) {
connectButton.setDisable(true);
new Thread(() -> {
if (isClientMode(HClient.FLASH)) {
if (autoDetectBox.isSelected()) {
getHConnection().start();
} else {
getHConnection().start(hostOptionsBox.getEditor().getText(), Integer.parseInt(portOptionsBox.getEditor().getText()));
}
} else if (isClientMode(HClient.UNITY)) {
getHConnection().startUnity();
} else if (isClientMode(HClient.NITRO)) {
getHConnection().startNitro();
}
if (GEarthProperties.isDebugModeEnabled())
System.out.println("connecting");
}).start();
} else {
getHConnection().abort();
}
}
private void selectClientType(HClient newValue) {
switch (newValue) {
case FLASH:
flashOption.setSelected(true);
break;
case UNITY:
unityOption.setSelected(true);
break;
case NITRO:
nitroOption.setSelected(true);
break;
}
}
private void updateInputUI() {
if (parentController == null) return;
final HConnection hConnection = getHConnection();
final HState hConnectionState = hConnection.getState();
clientTypeSelectionGrid.setDisable(hConnectionState != HState.NOT_CONNECTED);
connectedHotelVersionField.setText(hConnection.getHotelVersion());
connectButton.setDisable(hConnectionState == HState.PREPARING || hConnectionState == HState.ABORTING);
if (!autoDetectBox.isSelected() && !connectButton.isDisable() && useFlash()) {
try {
int i = Integer.parseInt(portOptionsBox.getEditor().getText());
connectButton.setDisable(i < 0 || i >= 256 * 256);
} catch (Exception e) {
connectButton.setDisable(true);
}
}
hostOptionsBox.setDisable(hConnectionState != HState.NOT_CONNECTED || autoDetectBox.isSelected());
portOptionsBox.setDisable(hConnectionState != HState.NOT_CONNECTED || autoDetectBox.isSelected());
autoDetectBox.setDisable(!useFlash());
connectedHostField.setDisable(!useFlash());
connectedPortField.setDisable(!useFlash());
hostOptionsBox.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || autoDetectBox.isSelected());
portOptionsBox.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || autoDetectBox.isSelected());
}
private void tryMaybeConnectOnInit() {
if (initCount.incrementAndGet() == 2)
maybeConnectOnInit();
}
private void maybeConnectOnInit() {
String connectMode = GEarth.getArgument("--connect", "-c");
if (connectMode != null) {
switch (connectMode) {
case "flash":
Platform.runLater(() -> flashOption.setSelected(true));
String host = GEarth.getArgument("--host");
String port = GEarth.getArgument("--port");
if (host != null && port != null) {
Platform.runLater(() -> {
if (!hostOptionsBox.getItems().contains(host))
hostOptionsBox.getItems().add(host);
hostOptionsBox.getSelectionModel().select(host);
if (!portOptionsBox.getItems().contains(port))
portOptionsBox.getItems().add(port);
portOptionsBox.getSelectionModel().select(port);
autoDetectBox.setSelected(false);
});
getHConnection().start(host, Integer.parseInt(port));
} else {
Platform.runLater(() -> autoDetectBox.setSelected(true));
getHConnection().start();
}
break;
case "unity":
Platform.runLater(() -> unityOption.setSelected(true));
getHConnection().startUnity();
break;
case "nitro":
Platform.runLater(() -> nitroOption.setSelected(true));
getHConnection().startNitro();
break;
}
Platform.runLater(this::updateInputUI);
}
}
public void changeClientMode() {
updateInputUI();
}
private boolean useFlash() {
return flashOption.isSelected();
}
private boolean isClientMode(HClient client) {
switch (client) {
case FLASH:
return flashOption.isSelected();
case UNITY:
return unityOption.isSelected();
case NITRO:
return nitroOption.isSelected();
}
return false;
}
private void initHostSelection() {
final List<String> knownHosts = ProxyProviderFactory.autoDetectHosts;
final Set<String> hosts = new HashSet<>();
final Set<String> ports = new HashSet<>();
for (String h : knownHosts) { for (String h : knownHosts) {
String[] split = h.split(":"); String[] split = h.split(":");
@ -92,228 +287,30 @@ public class ConnectionController extends SubForm {
} }
inpPort.getItems().addAll(portsSorted); portOptionsBox.getItems().addAll(portsSorted);
inpHost.getItems().addAll(hostsSorted); hostOptionsBox.getItems().addAll(hostsSorted);
inpPort.getSelectionModel().select(portSelectIndex); portOptionsBox.getSelectionModel().select(portSelectIndex);
inpHost.getSelectionModel().select(hostSelectIndex); hostOptionsBox.getSelectionModel().select(hostSelectIndex);
synchronized (lock) {
fullyInitialized++;
if (fullyInitialized == 2) {
Platform.runLater(this::updateInputUI);
}
}
synchronized (this) {
tryMaybeConnectOnInit();
}
initLanguageBinding();
}
private void selectClientType(HClient newValue) {
switch (newValue) {
case FLASH:
rd_flash.setSelected(true);
break;
case UNITY:
rd_unity.setSelected(true);
break;
case NITRO:
rd_nitro.setSelected(true);
break;
}
}
private void updateInputUI() {
if (parentController == null) return;
final HConnection hConnection = getHConnection();
final HState hConnectionState = hConnection.getState();
grd_clientSelection.setDisable(hConnectionState != HState.NOT_CONNECTED);
txtfield_hotelversion.setText(hConnection.getHotelVersion());
btnConnect.setDisable(hConnectionState == HState.PREPARING || hConnectionState == HState.ABORTING);
if (!cbx_autodetect.isSelected() && !btnConnect.isDisable() && useFlash()) {
try {
int i = Integer.parseInt(inpPort.getEditor().getText());
btnConnect.setDisable(i < 0 || i >= 256 * 256);
}
catch (Exception e) {
btnConnect.setDisable(true);
}
}
inpHost.setDisable(hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
inpPort.setDisable(hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
cbx_autodetect.setDisable(!useFlash());
outHost.setDisable(!useFlash());
outPort.setDisable(!useFlash());
inpHost.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
inpPort.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
}
public void onParentSet(){
synchronized (lock) {
fullyInitialized++;
if (fullyInitialized == 2) {
Platform.runLater(this::updateInputUI);
}
}
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> Platform.runLater(() -> {
updateInputUI();
if (newValue == HState.NOT_CONNECTED) {
state.setKey(0, "tab.connection.state.notconnected");
connect.setKey(0, "tab.connection.button.connect");
outHost.setText("");
outPort.setText("");
}
else if (oldValue == HState.NOT_CONNECTED)
connect.setKey(0, "tab.connection.button.abort");
if (newValue == HState.CONNECTED)
state.setKey(0, "tab.connection.state.connected");
if (newValue == HState.WAITING_FOR_CLIENT)
state.setKey(0, "tab.connection.state.waiting");
if (newValue == HState.CONNECTED && useFlash()) {
final String host = getHConnection().getDomain();
final int port = getHConnection().getServerPort();
outHost.setText(host);
outPort.setText(Integer.toString(port));
GEarthProperties.hostProperty.set(host);
GEarthProperties.portProperty.set(port);
}
}));
Platform.runLater(this::updateInputUI);
synchronized (this) {
tryMaybeConnectOnInit();
}
}
private void tryMaybeConnectOnInit() {
if (++initcount == 2) {
maybeConnectOnInit();
}
}
private void maybeConnectOnInit() {
String connectMode = GEarth.getArgument("--connect", "-c");
if (connectMode != null) {
if (connectMode.equals("flash")) {
Platform.runLater(() -> rd_flash.setSelected(true));
String host = GEarth.getArgument("--host");
String port = GEarth.getArgument("--port");
if (host != null && port != null) {
Platform.runLater(() -> {
if (!inpHost.getItems().contains(host))
inpHost.getItems().add(host);
inpHost.getSelectionModel().select(host);
if (!inpPort.getItems().contains(port))
inpPort.getItems().add(port);
inpPort.getSelectionModel().select(port);
cbx_autodetect.setSelected(false);
});
getHConnection().start(host, Integer.parseInt(port));
}
else {
Platform.runLater(() -> cbx_autodetect.setSelected(true));
getHConnection().start();
}
}
else if (connectMode.equals("unity")) {
Platform.runLater(() -> rd_unity.setSelected(true));
getHConnection().startUnity();
}
else if (connectMode.equals("nitro")) {
Platform.runLater(() -> rd_nitro.setSelected(true));
getHConnection().startNitro();
}
Platform.runLater(this::updateInputUI);
}
}
public void btnConnect_clicked(ActionEvent actionEvent) {
if (getHConnection().getState() == HState.NOT_CONNECTED) {
btnConnect.setDisable(true);
new Thread(() -> {
if (isClientMode(HClient.FLASH)) {
if (cbx_autodetect.isSelected()) {
getHConnection().start();
} else {
getHConnection().start(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
}
} else if (isClientMode(HClient.UNITY)) {
getHConnection().startUnity();
} else if (isClientMode(HClient.NITRO)) {
getHConnection().startNitro();
}
if (GEarthProperties.isDebugModeEnabled())
System.out.println("connecting");
}).start();
}
else {
getHConnection().abort();
}
}
@Override
protected void onExit() {
GEarthProperties.clientTypeProperty.set(
rd_flash.isSelected() ? HClient.FLASH
: rd_unity.isSelected() ? HClient.UNITY
: HClient.NITRO);
getHConnection().abort();
}
public void changeClientMode() {
updateInputUI();
}
private boolean useFlash() {
return rd_flash.isSelected();
}
private boolean isClientMode(HClient client) {
switch (client) {
case FLASH:
return rd_flash.isSelected();
case UNITY:
return rd_unity.isSelected();
case NITRO:
return rd_nitro.isSelected();
}
return false;
} }
private void initLanguageBinding() { private void initLanguageBinding() {
TranslatableString port = new TranslatableString("%s", "tab.connection.port"); TranslatableString port = new TranslatableString("%s", "tab.connection.port");
TranslatableString host = new TranslatableString("%s", "tab.connection.host"); TranslatableString host = new TranslatableString("%s", "tab.connection.host");
lblInpPort.textProperty().bind(port); portOptionsLabel.textProperty().bind(port);
lblInpHost.textProperty().bind(host); hostOptionsLabel.textProperty().bind(host);
lblPort.textProperty().bind(port); connectedPortLabel.textProperty().bind(port);
lblHost.textProperty().bind(host); connectedHostLabel.textProperty().bind(host);
cbx_autodetect.textProperty().bind(new TranslatableString("%s", "tab.connection.autodetect")); autoDetectBox.textProperty().bind(new TranslatableString("%s", "tab.connection.autodetect"));
connect = new TranslatableString("%s", "tab.connection.button.connect"); connect = new TranslatableString("%s", "tab.connection.button.connect");
btnConnect.textProperty().bind(connect); connectButton.textProperty().bind(connect);
lblHotelVersion.textProperty().bind(new TranslatableString("%s", "tab.connection.version")); connectedHotelVersionLabel.textProperty().bind(new TranslatableString("%s", "tab.connection.version"));
lblClient.textProperty().bind(new TranslatableString("%s", "tab.connection.client")); selectedClientLabel.textProperty().bind(new TranslatableString("%s", "tab.connection.client"));
rd_unity.textProperty().bind(new TranslatableString("%s", "tab.connection.client.unity")); unityOption.textProperty().bind(new TranslatableString("%s", "tab.connection.client.unity"));
rd_flash.textProperty().bind(new TranslatableString("%s", "tab.connection.client.flash")); flashOption.textProperty().bind(new TranslatableString("%s", "tab.connection.client.flash"));
rd_nitro.textProperty().bind(new TranslatableString("%s", "tab.connection.client.nitro")); nitroOption.textProperty().bind(new TranslatableString("%s", "tab.connection.client.nitro"));
lblStateHead.textProperty().bind(new TranslatableString("%s", "tab.connection.state")); connectionStateHeaderLabel.textProperty().bind(new TranslatableString("%s", "tab.connection.state"));
state = new TranslatableString("%s", "tab.connection.state.notconnected"); state = new TranslatableString("%s", "tab.connection.state.notconnected");
lblState.textProperty().bind(state); notConnectedStateLabel.textProperty().bind(state);
} }
} }

View File

@ -10,8 +10,8 @@ import javafx.scene.layout.VBox;
*/ */
public class ExtensionItemContainerProducer { public class ExtensionItemContainerProducer {
private VBox parent; private final VBox parent;
private ScrollPane scrollPane; private final ScrollPane scrollPane;
private final Object lock = new Object(); private final Object lock = new Object();
private int port = -1; private int port = -1;

View File

@ -2,8 +2,8 @@ package gearth.ui.subforms.extensions;
import gearth.services.extension_handler.ExtensionHandler; import gearth.services.extension_handler.ExtensionHandler;
import gearth.services.extension_handler.extensions.ExtensionListener; import gearth.services.extension_handler.extensions.ExtensionListener;
import gearth.services.extension_handler.extensions.implementations.network.NetworkExtensionServer;
import gearth.services.extension_handler.extensions.implementations.network.NetworkExtensionAuthenticator; import gearth.services.extension_handler.extensions.implementations.network.NetworkExtensionAuthenticator;
import gearth.services.extension_handler.extensions.implementations.network.NetworkExtensionServer;
import gearth.services.extension_handler.extensions.implementations.network.executer.ExecutionInfo; import gearth.services.extension_handler.extensions.implementations.network.executer.ExecutionInfo;
import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunner; import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunner;
import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunnerFactory; import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunnerFactory;
@ -14,52 +14,68 @@ import gearth.ui.subforms.extensions.logger.ExtensionLogger;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString; import gearth.ui.translations.TranslatableString;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.event.ActionEvent; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import java.io.File; import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Created by Jonas on 06/04/18. * Created by Jonas on 06/04/18.
*/ */
public class ExtensionsController extends SubForm implements Initializable {
public class ExtensionsController extends SubForm { public Button installButton;
public TextField portField;
public GridPane headerGridPane;
public ScrollPane contentScrollPane;
public VBox contentBox;
public Button btn_install; public Button viewLogsButton;
public TextField ext_port; public Button openGPythonShellButton;
public VBox extensioncontainer;
public GridPane header_ext; public Label
public ScrollPane scroller; tableTitleLabel,
public Button btn_viewExtensionConsole; tableDescriptionLabel,
public Button btn_gpython; tableAuthorLabel,
tableVersionLabel,
tableEditLabel,
portLabel;
private ExtensionRunner extensionRunner = null; private ExtensionRunner extensionRunner = null;
private ExtensionHandler extensionHandler; private ExtensionHandler extensionHandler;
private NetworkExtensionServer networkExtensionsProducer; // needed for port private NetworkExtensionServer networkExtensionsProducer; // needed for port
private ExtensionLogger extensionLogger = null; private ExtensionLogger extensionLogger = null;
public Label lbl_tableTitle, lbl_tableDesc, lbl_tableAuthor, lbl_tableVersion, lbl_tableEdit, lbl_port; private final AtomicInteger gpytonShellCounter = new AtomicInteger(1);
private final AtomicBoolean pythonShellLaunching = new AtomicBoolean(false);
@Override
public void initialize() { public void initialize(URL location, ResourceBundle resources) {
scroller.widthProperty().addListener(observable -> header_ext.setPrefWidth(scroller.getWidth()));
extensionLogger = new ExtensionLogger(); extensionLogger = new ExtensionLogger();
btn_install.disableProperty().bind(GEarthProperties.enableDeveloperModeProperty.not()); headerGridPane.prefWidthProperty().bind(contentScrollPane.widthProperty());
installButton.disableProperty().bind(GEarthProperties.enableDeveloperModeProperty.not());
initLanguageBinding(); initLanguageBinding();
} }
@Override
protected void onParentSet() { protected void onParentSet() {
ExtensionItemContainerProducer producer = new ExtensionItemContainerProducer(extensioncontainer, scroller); ExtensionItemContainerProducer producer = new ExtensionItemContainerProducer(contentBox, contentScrollPane);
extensionHandler = new ExtensionHandler(getHConnection()); extensionHandler = new ExtensionHandler(getHConnection());
extensionHandler.getObservable().addListener((e -> { extensionHandler.getObservable().addListener((e -> Platform.runLater(() -> producer.extensionConnected(e))));
Platform.runLater(() -> producer.extensionConnected(e));
}));
//noinspection OptionalGetWithoutIsPresent //noinspection OptionalGetWithoutIsPresent
networkExtensionsProducer networkExtensionsProducer
@ -67,42 +83,20 @@ public class ExtensionsController extends SubForm {
.filter(producer1 -> producer1 instanceof NetworkExtensionServer) .filter(producer1 -> producer1 instanceof NetworkExtensionServer)
.findFirst().get(); .findFirst().get();
producer.setPort(networkExtensionsProducer.getPort()); producer.setPort(networkExtensionsProducer.getPort());
ext_port.setText(networkExtensionsProducer.getPort()+""); portField.setText(Integer.toString(networkExtensionsProducer.getPort()));
// System.out.println("Extension server registered on port: " + extensionsRegistrer.getPort());
extensionRunner = ExtensionRunnerFactory.get(); extensionRunner = ExtensionRunnerFactory.get();
extensionRunner.runAllExtensions(networkExtensionsProducer.getPort()); extensionRunner.runAllExtensions(networkExtensionsProducer.getPort());
extensionHandler.getObservable().addListener(e ->
extensionHandler.getObservable().addListener(e -> e.getExtensionObservable().addListener(new ExtensionListener() { e.getExtensionObservable().addListener(new ExtensionListener() {
@Override @Override
public void log(String text) { public void log(String text) {
extensionLogger.log(text); extensionLogger.log(text);
} }
})); })
} );
public void installBtnClicked(ActionEvent actionEvent) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(LanguageBundle.get("tab.extensions.button.install.windowtitle"));
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter(LanguageBundle.get("tab.extensions.button.install.filetype"), ExecutionInfo.ALLOWED_EXTENSION_TYPES));
File selectedFile = fileChooser.showOpenDialog(parentController.getStage());
if (selectedFile != null) {
extensionRunner.installAndRunExtension(selectedFile.getPath(), networkExtensionsProducer.getPort());
}
}
public void extConsoleBtnClicked(ActionEvent actionEvent) {
if (!extensionLogger.isVisible()) {
extensionLogger.show();
}
else {
extensionLogger.hide();
}
} }
@Override @Override
@ -110,47 +104,63 @@ public class ExtensionsController extends SubForm {
updateGPythonStatus(); updateGPythonStatus();
} }
public void updateGPythonStatus() { @FXML
if (!pythonShellLaunching) { public void onClickInstallButton() {
btn_gpython.setDisable(!parentController.extraController.useGPython()); final FileChooser fileChooser = new FileChooser();
} fileChooser.setTitle(LanguageBundle.get("tab.extensions.button.install.windowtitle"));
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter(LanguageBundle.get("tab.extensions.button.install.filetype"), ExecutionInfo.ALLOWED_EXTENSION_TYPES));
final File selectedFile = fileChooser.showOpenDialog(parentController.getStage());
if (selectedFile != null)
extensionRunner.installAndRunExtension(selectedFile.getPath(), networkExtensionsProducer.getPort());
} }
public void setLocalInstallingEnabled(boolean enabled) { @FXML
btn_install.setDisable(!enabled); public void onClickLogsButton() {
if (!extensionLogger.isVisible())
extensionLogger.show();
else
extensionLogger.hide();
} }
private volatile int gpytonShellCounter = 1; @FXML
private volatile boolean pythonShellLaunching = false; public void onClickGPythonShellButton() {
public void gpythonBtnClicked(ActionEvent actionEvent) { pythonShellLaunching.set(true);
pythonShellLaunching = true; Platform.runLater(() -> openGPythonShellButton.setDisable(true));
Platform.runLater(() -> btn_gpython.setDisable(true));
GPythonShell shell = new GPythonShell( GPythonShell shell = new GPythonShell(
String.format("%s %d", LanguageBundle.get("tab.extensions.button.pythonshell.windowtitle"),gpytonShellCounter++), String.format("%s %d",
LanguageBundle.get("tab.extensions.button.pythonshell.windowtitle"),
gpytonShellCounter.getAndIncrement()
),
networkExtensionsProducer.getPort(), networkExtensionsProducer.getPort(),
NetworkExtensionAuthenticator.generatePermanentCookie() NetworkExtensionAuthenticator.generatePermanentCookie()
); );
shell.launch((b) -> { shell.launch((b) -> {
pythonShellLaunching = false; pythonShellLaunching.set(false);
Platform.runLater(this::updateGPythonStatus); Platform.runLater(this::updateGPythonStatus);
}); });
} }
public void updateGPythonStatus() {
if (!pythonShellLaunching.get())
openGPythonShellButton.setDisable(!parentController.extraController.useGPython());
}
public ExtensionHandler getExtensionHandler() { public ExtensionHandler getExtensionHandler() {
return extensionHandler; return extensionHandler;
} }
private void initLanguageBinding() { private void initLanguageBinding() {
lbl_tableTitle.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.title")); tableTitleLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.title"));
lbl_tableDesc.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.description")); tableDescriptionLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.description"));
lbl_tableAuthor.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.author")); tableAuthorLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.author"));
lbl_tableVersion.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.version")); tableVersionLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.version"));
lbl_tableEdit.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.edit")); tableEditLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.edit"));
lbl_port.textProperty().bind(new TranslatableString("%s:", "tab.extensions.port")); portLabel.textProperty().bind(new TranslatableString("%s:", "tab.extensions.port"));
btn_gpython.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.pythonshell")); openGPythonShellButton.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.pythonshell"));
btn_viewExtensionConsole.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.logs")); viewLogsButton.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.logs"));
btn_install.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.install")); installButton.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.install"));
} }
} }

View File

@ -1,14 +1,11 @@
package gearth.ui.subforms.extensions.logger; package gearth.ui.subforms.extensions.logger;
import gearth.GEarth;
import gearth.ui.titlebar.DefaultTitleBarConfig;
import gearth.ui.titlebar.GEarthThemedTitleBarConfig; import gearth.ui.titlebar.GEarthThemedTitleBarConfig;
import gearth.ui.titlebar.TitleBarController; import gearth.ui.titlebar.TitleBarController;
import gearth.ui.translations.TranslatableString; import gearth.ui.translations.TranslatableString;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Modality; import javafx.stage.Modality;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -17,6 +14,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ExtensionLogger { public class ExtensionLogger {
private Stage stage; private Stage stage;
private ExtensionLoggerController controller = null; private ExtensionLoggerController controller = null;

View File

@ -1,5 +1,6 @@
package gearth.ui.subforms.extensions.logger; package gearth.ui.subforms.extensions.logger;
import gearth.misc.StringUtils;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
@ -12,15 +13,14 @@ import java.net.URL;
import java.util.*; import java.util.*;
public class ExtensionLoggerController implements Initializable { public class ExtensionLoggerController implements Initializable {
public BorderPane borderPane; public BorderPane borderPane;
private Stage stage = null;
private StyleClassedTextArea area; private StyleClassedTextArea area;
private volatile boolean initialized = false; private volatile boolean initialized = false;
private final List<Element> appendOnLoad = new ArrayList<>(); private final List<Element> appendOnLoad = new ArrayList<>();
@Override @Override
public void initialize(URL arg0, ResourceBundle arg1) { public void initialize(URL arg0, ResourceBundle arg1) {
area = new StyleClassedTextArea(); area = new StyleClassedTextArea();
@ -44,8 +44,8 @@ public class ExtensionLoggerController implements Initializable {
private synchronized void appendLog(List<Element> elements) { private synchronized void appendLog(List<Element> elements) {
Platform.runLater(() -> { Platform.runLater(() -> {
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
StyleSpansBuilder<Collection<String>> styleSpansBuilder = new StyleSpansBuilder<>(0); final StyleSpansBuilder<Collection<String>> styleSpansBuilder = new StyleSpansBuilder<>(0);
for (Element element : elements) { for (Element element : elements) {
sb.append(element.text); sb.append(element.text);
@ -66,7 +66,7 @@ public class ExtensionLoggerController implements Initializable {
} }
void log(String s) { void log(String s) {
s = cleanTextContent(s); s = StringUtils.cleanTextContent(s);
ArrayList<Element> elements = new ArrayList<>(); ArrayList<Element> elements = new ArrayList<>();
String classname, text; String classname, text;
@ -98,21 +98,6 @@ public class ExtensionLoggerController implements Initializable {
} }
void setStage(Stage stage) { void setStage(Stage stage) {
this.stage = stage;
}
private static String cleanTextContent(String text)
{
// // strips off all non-ASCII characters
// text = text.replaceAll("[^\\x00-\\x7F]", "");
//
// // erases all the ASCII control characters
text = text.replaceAll("[\\p{Cntrl}&&[^\n\t]]", "");
// removes non-printable characters from Unicode
// text = text.replaceAll("\\p{C}", "");
return text.trim();
} }
} }

View File

@ -2,6 +2,7 @@ package gearth.ui.subforms.extra;
import gearth.GEarth; import gearth.GEarth;
import gearth.misc.BindingsUtil; import gearth.misc.BindingsUtil;
import gearth.misc.HyperLinkUtil;
import gearth.protocol.connection.HState; import gearth.protocol.connection.HState;
import gearth.protocol.connection.proxy.ProxyProviderFactory; import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.SocksConfiguration; import gearth.protocol.connection.proxy.SocksConfiguration;
@ -9,79 +10,82 @@ import gearth.services.always_admin.AdminService;
import gearth.services.g_python.GPythonVersionUtils; import gearth.services.g_python.GPythonVersionUtils;
import gearth.ui.GEarthProperties; import gearth.ui.GEarthProperties;
import gearth.ui.SubForm; import gearth.ui.SubForm;
import gearth.ui.subforms.info.InfoController;
import gearth.ui.titlebar.TitleBarController; import gearth.ui.titlebar.TitleBarController;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString; import gearth.ui.translations.TranslatableString;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent; import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import java.io.IOException; import java.io.IOException;
import java.net.URL;
import java.util.Optional; import java.util.Optional;
import java.util.ResourceBundle;
/** /**
* Created by Jonas on 06/04/18. * Created by Jonas on 06/04/18.
* TODO: add setup link to g-earth wiki
*/ */
public class ExtraController extends SubForm implements SocksConfiguration { public class ExtraController extends SubForm implements SocksConfiguration, Initializable {
public static final String INFO_URL_GPYTHON = "https://github.com/sirjonasxx/G-Earth/wiki/G-Python-qtConsole"; public static final String INFO_URL_GPYTHON = "https://github.com/sirjonasxx/G-Earth/wiki/G-Python-qtConsole";
public TextArea notepadTextArea;
public TextArea txtarea_notepad; public CheckBox alwaysOnTopBox;
public Hyperlink troubleshootingLink;
public CheckBox cbx_alwaysOnTop; public CheckBox enableClientSideStaffPermissionsBox;
public Hyperlink url_troubleshooting; public CheckBox enableDeveloperModeBox;
//TODO add setup link to g-earth wiki public CheckBox enableGPythonBox;
public CheckBox cbx_gpython; public CheckBox enableAdvancedBox;
public CheckBox cbx_advanced; public GridPane advancedPane;
public GridPane grd_advanced; public CheckBox advancedDisableDecryptionBox;
public CheckBox advancedEnableDebugBox;
public CheckBox advancedUseSocksBox;
public GridPane advancedSocksInfoGrid;
public TextField advancedSocketProxyIpField;
public CheckBox cbx_disableDecryption; public Label notepadLabel, advancedSocksProxyIpLabel;
public CheckBox cbx_debug;
public CheckBox cbx_useSocks;
public GridPane grd_socksInfo;
public TextField txt_socksIp;
public CheckBox cbx_admin;
public Label lbl_notepad, lbl_proxyIp;
public CheckBox cbx_develop;
private AdminService adminService; private AdminService adminService;
public void initialize() { @Override
url_troubleshooting.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting")); public void initialize(URL location, ResourceBundle resources) {
InfoController.activateHyperlink(url_troubleshooting);
BindingsUtil.setAndBindBiDirectional(txtarea_notepad.textProperty(), GEarthProperties.notesProperty); troubleshootingLink.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting"));
HyperLinkUtil.showDocumentOnClick(troubleshootingLink);
txt_socksIp.textProperty().set(GEarthProperties.getSocksHost()+":"+GEarthProperties.getSocksPort()); BindingsUtil.setAndBindBiDirectional(notepadTextArea.textProperty(), GEarthProperties.notesProperty);
GEarthProperties.socksHostProperty.bind(Bindings.createStringBinding(this::getSocksHost, txt_socksIp.textProperty()));
GEarthProperties.socksPortProperty.bind(Bindings.createIntegerBinding(this::getSocksPort, txt_socksIp.textProperty()));
grd_socksInfo.disableProperty().bind(GEarthProperties.enableSocksProperty.not());
BindingsUtil.setAndBindBiDirectional(cbx_useSocks.selectedProperty(), GEarthProperties.enableSocksProperty); advancedSocketProxyIpField.textProperty().set(GEarthProperties.getSocksHost()+":"+GEarthProperties.getSocksPort());
GEarthProperties.socksHostProperty.bind(Bindings.createStringBinding(this::getSocksHost, advancedSocketProxyIpField.textProperty()));
GEarthProperties.socksPortProperty.bind(Bindings.createIntegerBinding(this::getSocksPort, advancedSocketProxyIpField.textProperty()));
advancedSocksInfoGrid.disableProperty().bind(GEarthProperties.enableSocksProperty.not());
BindingsUtil.setAndBindBiDirectional(advancedUseSocksBox.selectedProperty(), GEarthProperties.enableSocksProperty);
ProxyProviderFactory.setSocksConfig(this); ProxyProviderFactory.setSocksConfig(this);
BindingsUtil.setAndBindBiDirectional(cbx_debug.selectedProperty(), GEarthProperties.enableDebugProperty); BindingsUtil.setAndBindBiDirectional(advancedEnableDebugBox.selectedProperty(), GEarthProperties.enableDebugProperty);
BindingsUtil.setAndBindBiDirectional(cbx_disableDecryption.selectedProperty(), GEarthProperties.disablePacketDecryptionProperty); BindingsUtil.setAndBindBiDirectional(advancedDisableDecryptionBox.selectedProperty(), GEarthProperties.disablePacketDecryptionProperty);
BindingsUtil.setAndBindBiDirectional(cbx_alwaysOnTop.selectedProperty(), GEarthProperties.alwaysOnTopProperty); BindingsUtil.setAndBindBiDirectional(alwaysOnTopBox.selectedProperty(), GEarthProperties.alwaysOnTopProperty);
BindingsUtil.setAndBindBiDirectional(cbx_develop.selectedProperty(), GEarthProperties.enableDeveloperModeProperty); BindingsUtil.setAndBindBiDirectional(enableDeveloperModeBox.selectedProperty(), GEarthProperties.enableDeveloperModeProperty);
BindingsUtil.setAndBindBiDirectional(cbx_admin.selectedProperty(), GEarthProperties.alwaysAdminProperty); BindingsUtil.setAndBindBiDirectional(enableClientSideStaffPermissionsBox.selectedProperty(), GEarthProperties.alwaysAdminProperty);
BindingsUtil.setAndBindBiDirectional(cbx_gpython.selectedProperty(), GEarthProperties.enableGPythonProperty); BindingsUtil.setAndBindBiDirectional(enableGPythonBox.selectedProperty(), GEarthProperties.enableGPythonProperty);
initLanguageBinding(); initLanguageBinding();
} }
@Override @Override
protected void onParentSet() { protected void onParentSet() {
adminService = new AdminService(cbx_admin.isSelected(), getHConnection()); adminService = new AdminService(enableClientSideStaffPermissionsBox.isSelected(), getHConnection());
getHConnection().addTrafficListener(1, message -> adminService.onMessage(message)); getHConnection().addTrafficListener(1, message -> adminService.onMessage(message));
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> { getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == HState.CONNECTED) if (newValue == HState.CONNECTED)
@ -89,31 +93,18 @@ public class ExtraController extends SubForm implements SocksConfiguration {
if (oldValue == HState.NOT_CONNECTED || newValue == HState.NOT_CONNECTED) if (oldValue == HState.NOT_CONNECTED || newValue == HState.NOT_CONNECTED)
updateAdvancedUI(); updateAdvancedUI();
}); });
cbx_advanced.selectedProperty().addListener(observable -> updateAdvancedUI()); enableAdvancedBox.selectedProperty().addListener(observable -> updateAdvancedUI());
updateAdvancedUI(); updateAdvancedUI();
} }
private void updateAdvancedUI() {
if (!cbx_advanced.isSelected()) {
cbx_debug.setSelected(false);
cbx_useSocks.setSelected(false);
if (getHConnection().getState() == HState.NOT_CONNECTED) {
cbx_disableDecryption.setSelected(false);
}
}
grd_advanced.setDisable(!cbx_advanced.isSelected());
cbx_disableDecryption.setDisable(getHConnection().getState() != HState.NOT_CONNECTED);
}
@Override @Override
public boolean useSocks() { public boolean useSocks() {
return cbx_useSocks.isSelected(); return advancedUseSocksBox.isSelected();
} }
@Override @Override
public int getSocksPort() { public int getSocksPort() {
String socksString = txt_socksIp.getText(); String socksString = advancedSocketProxyIpField.getText();
if (socksString.contains(":")) { if (socksString.contains(":")) {
return Integer.parseInt(socksString.split(":")[1]); return Integer.parseInt(socksString.split(":")[1]);
} }
@ -122,7 +113,7 @@ public class ExtraController extends SubForm implements SocksConfiguration {
@Override @Override
public String getSocksHost() { public String getSocksHost() {
return txt_socksIp.getText().split(":")[0]; return advancedSocketProxyIpField.getText().split(":")[0];
} }
@Override @Override
@ -130,17 +121,13 @@ public class ExtraController extends SubForm implements SocksConfiguration {
// return cbx_socksUseIfNeeded.isSelected(); // return cbx_socksUseIfNeeded.isSelected();
return false; return false;
} }
@FXML
public boolean useGPython() { public void onClickGPythonButton() {
return cbx_gpython.isSelected(); if (enableGPythonBox.isSelected()) {
}
public void gpythonCbxClick(ActionEvent actionEvent) {
if (cbx_gpython.isSelected()) {
new Thread(() -> { new Thread(() -> {
Platform.runLater(() -> { Platform.runLater(() -> {
cbx_gpython.setSelected(false); enableGPythonBox.setSelected(false);
cbx_gpython.setDisable(true); enableGPythonBox.setDisable(true);
}); });
if (!GPythonVersionUtils.validInstallation()) { if (!GPythonVersionUtils.validInstallation()) {
Platform.runLater(() -> { Platform.runLater(() -> {
@ -166,13 +153,13 @@ public class ExtraController extends SubForm implements SocksConfiguration {
e.printStackTrace(); e.printStackTrace();
} }
cbx_gpython.setDisable(false); enableGPythonBox.setDisable(false);
}); });
} }
else { else {
Platform.runLater(() -> { Platform.runLater(() -> {
cbx_gpython.setSelected(true); enableGPythonBox.setSelected(true);
cbx_gpython.setDisable(false); enableGPythonBox.setDisable(false);
parentController.extensionsController.updateGPythonStatus(); parentController.extensionsController.updateGPythonStatus();
}); });
} }
@ -183,8 +170,9 @@ public class ExtraController extends SubForm implements SocksConfiguration {
} }
public void developCbxClick(ActionEvent actionEvent) { @FXML
if (cbx_develop.isSelected()) { public void onClickDeveloperModeBox() {
if (enableDeveloperModeBox.isSelected()) {
Platform.runLater(() -> { Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("tab.extra.options.developmode.alert.title"), ButtonType.NO, ButtonType.YES); Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("tab.extra.options.developmode.alert.title"), ButtonType.NO, ButtonType.YES);
alert.setTitle(LanguageBundle.get("tab.extra.options.developmode.alert.title")); alert.setTitle(LanguageBundle.get("tab.extra.options.developmode.alert.title"));
@ -197,7 +185,7 @@ public class ExtraController extends SubForm implements SocksConfiguration {
try { try {
Optional<ButtonType> result = TitleBarController.create(alert).showAlertAndWait(); Optional<ButtonType> result = TitleBarController.create(alert).showAlertAndWait();
if (!result.isPresent() || result.get() == ButtonType.NO) { if (!result.isPresent() || result.get() == ButtonType.NO) {
cbx_develop.setSelected(false); enableDeveloperModeBox.setSelected(false);
} }
else { else {
setDevelopMode(true); setDevelopMode(true);
@ -212,29 +200,47 @@ public class ExtraController extends SubForm implements SocksConfiguration {
} }
} }
private void setDevelopMode(boolean enabled) { @FXML
cbx_develop.setSelected(enabled); public void onClickClientSideStaffPermissionsBox() {
adminService.setEnabled(enableClientSideStaffPermissionsBox.isSelected());
} }
public void adminCbxClick(ActionEvent actionEvent) { public boolean useGPython() {
adminService.setEnabled(cbx_admin.isSelected()); return enableGPythonBox.isSelected();
}
private void setDevelopMode(boolean enabled) {
enableDeveloperModeBox.setSelected(enabled);
}
private void updateAdvancedUI() {
if (!enableAdvancedBox.isSelected()) {
advancedEnableDebugBox.setSelected(false);
advancedUseSocksBox.setSelected(false);
if (getHConnection().getState() == HState.NOT_CONNECTED) {
advancedDisableDecryptionBox.setSelected(false);
}
}
advancedPane.setDisable(!enableAdvancedBox.isSelected());
advancedDisableDecryptionBox.setDisable(getHConnection().getState() != HState.NOT_CONNECTED);
} }
private void initLanguageBinding() { private void initLanguageBinding() {
url_troubleshooting.textProperty().bind(new TranslatableString("%s", "tab.extra.troubleshooting")); troubleshootingLink.textProperty().bind(new TranslatableString("%s", "tab.extra.troubleshooting"));
lbl_notepad.textProperty().bind(new TranslatableString("%s:", "tab.extra.notepad")); notepadLabel.textProperty().bind(new TranslatableString("%s:", "tab.extra.notepad"));
lbl_proxyIp.textProperty().bind(new TranslatableString("%s:", "tab.extra.options.advanced.proxy.ip")); advancedSocksProxyIpLabel.textProperty().bind(new TranslatableString("%s:", "tab.extra.options.advanced.proxy.ip"));
cbx_alwaysOnTop.textProperty().bind(new TranslatableString("%s", "tab.extra.options.alwaysontop")); alwaysOnTopBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.alwaysontop"));
cbx_develop.textProperty().bind(new TranslatableString("%s", "tab.extra.options.developmode")); enableDeveloperModeBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.developmode"));
cbx_admin.textProperty().bind(new TranslatableString("%s", "tab.extra.options.staffpermissions")); enableClientSideStaffPermissionsBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.staffpermissions"));
cbx_gpython.textProperty().bind(new TranslatableString("%s", "tab.extra.options.pythonscripting")); enableGPythonBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.pythonscripting"));
cbx_advanced.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced")); enableAdvancedBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced"));
cbx_useSocks.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.socks")); advancedUseSocksBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.socks"));
cbx_disableDecryption.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.disabledecryption")); advancedDisableDecryptionBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.disabledecryption"));
cbx_debug.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.debugstdout")); advancedEnableDebugBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.debugstdout"));
} }
} }

View File

@ -1,6 +1,7 @@
package gearth.ui.subforms.info; package gearth.ui.subforms.info;
import gearth.GEarth; import gearth.misc.BindingsUtil;
import gearth.misc.HyperLinkUtil;
import gearth.ui.GEarthProperties; import gearth.ui.GEarthProperties;
import gearth.ui.titlebar.TitleBarController; import gearth.ui.titlebar.TitleBarController;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
@ -21,58 +22,58 @@ import java.util.ResourceBundle;
* Created by Jonas on 06/04/18. * Created by Jonas on 06/04/18.
*/ */
public class InfoController extends SubForm implements Initializable { public class InfoController extends SubForm implements Initializable {
public ImageView img_logo;
public Hyperlink link_darkbox;
public Hyperlink link_g_gearth;
public Hyperlink link_g_tanji;
public Hyperlink link_d_gearth;
public Hyperlink link_g_store;
public Hyperlink link_t_gearth;
public Label version, lbl_description, lbl_createdBy, lbl_contrib, lbl_links; private static final String PUBKEY = "1GEarthEV9Ua3RcixsKTcuc1PPZd9hqri3";
public Button btn_donate;
public static void activateHyperlink(Hyperlink link) { public ImageView logoImageView;
link.setOnAction((ActionEvent event) -> { public Hyperlink darkBoxLink;
Hyperlink h = (Hyperlink) event.getTarget(); public Hyperlink githubGEarthLink;
String s = h.getTooltip().getText(); public Hyperlink githubTanjiLink;
GEarth.main.getHostServices().showDocument(s); public Hyperlink discordGEarthLink;
event.consume(); public Hyperlink githubExtensionStoreLink;
}); public Hyperlink twitterGEarthLink;
}
public Label
themeTitleLabel,
descriptionLabel,
createdByLabel,
contributorsLabel,
linksLabel;
public Button donateButton;
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
img_logo.imageProperty().bind(GEarthProperties.logoImageBinding); BindingsUtil.setAndBind(logoImageView.imageProperty(), GEarthProperties.logoImageBinding);
version.textProperty().bind(GEarthProperties.themeTitleBinding); BindingsUtil.setAndBind(themeTitleLabel.textProperty(), GEarthProperties.themeTitleBinding);
link_darkbox.setTooltip(new Tooltip("https://darkbox.nl")); darkBoxLink.setTooltip(new Tooltip("https://darkbox.nl"));
link_d_gearth.setTooltip(new Tooltip("https://discord.gg/AVkcF8y")); discordGEarthLink.setTooltip(new Tooltip("https://discord.gg/AVkcF8y"));
link_g_gearth.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth")); githubGEarthLink.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth"));
link_g_tanji.setTooltip(new Tooltip("https://github.com/ArachisH/Tanji")); githubTanjiLink.setTooltip(new Tooltip("https://github.com/ArachisH/Tanji"));
link_g_store.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-ExtensionStore")); githubExtensionStoreLink.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-ExtensionStore"));
link_t_gearth.setTooltip(new Tooltip("https://twitter.com/Scripting_Habbo")); twitterGEarthLink.setTooltip(new Tooltip("https://twitter.com/Scripting_Habbo"));
activateHyperlink(link_darkbox); HyperLinkUtil.showDocumentOnClick(darkBoxLink);
activateHyperlink(link_d_gearth); HyperLinkUtil.showDocumentOnClick(discordGEarthLink);
activateHyperlink(link_g_gearth); HyperLinkUtil.showDocumentOnClick(githubGEarthLink);
activateHyperlink(link_g_tanji); HyperLinkUtil.showDocumentOnClick(githubTanjiLink);
activateHyperlink(link_g_store); HyperLinkUtil.showDocumentOnClick(githubExtensionStoreLink);
activateHyperlink(link_t_gearth); HyperLinkUtil.showDocumentOnClick(twitterGEarthLink);
initLanguageBinding(); initLanguageBinding();
} }
public void donate(ActionEvent actionEvent) {
String pubkey = "1GEarthEV9Ua3RcixsKTcuc1PPZd9hqri3";
Alert alert = new Alert(Alert.AlertType.INFORMATION, LanguageBundle.get("tab.info.donate.alert.title"), ButtonType.OK); public void donate(ActionEvent actionEvent) {
final Alert alert = new Alert(Alert.AlertType.INFORMATION, LanguageBundle.get("tab.info.donate.alert.title"), ButtonType.OK);
alert.setHeaderText(LanguageBundle.get("tab.info.donate.alert.title")); alert.setHeaderText(LanguageBundle.get("tab.info.donate.alert.title"));
VBox test = new VBox(); final VBox test = new VBox();
test.getChildren().add(new Label(LanguageBundle.get("tab.info.donate.alert.content"))); test.getChildren().add(new Label(LanguageBundle.get("tab.info.donate.alert.content")));
TextArea pubText = new TextArea(pubkey); final TextArea pubText = new TextArea(PUBKEY);
pubText.setPrefHeight(28); pubText.setPrefHeight(28);
pubText.setMaxWidth(250); pubText.setMaxWidth(250);
test.getChildren().add(pubText); test.getChildren().add(pubText);
@ -88,12 +89,11 @@ public class InfoController extends SubForm implements Initializable {
} }
private void initLanguageBinding() { private void initLanguageBinding() {
lbl_description.textProperty().bind(new TranslatableString("%s", "tab.info.description")); descriptionLabel.textProperty().bind(new TranslatableString("%s", "tab.info.description"));
lbl_createdBy.textProperty().bind(new TranslatableString("%s:", "tab.info.createdby")); createdByLabel.textProperty().bind(new TranslatableString("%s:", "tab.info.createdby"));
lbl_contrib.textProperty().bind(new TranslatableString("%s:", "tab.info.contributors")); contributorsLabel.textProperty().bind(new TranslatableString("%s:", "tab.info.contributors"));
lbl_links.textProperty().bind(new TranslatableString("%s:", "tab.info.links")); linksLabel.textProperty().bind(new TranslatableString("%s:", "tab.info.links"));
btn_donate.textProperty().bind(new TranslatableString("%s", "tab.info.donate")); donateButton.textProperty().bind(new TranslatableString("%s", "tab.info.donate"));
} }
} }

View File

@ -1,6 +1,5 @@
package gearth.ui.subforms.injection; package gearth.ui.subforms.injection;
import gearth.GEarth;
import gearth.misc.StringifyAble; import gearth.misc.StringifyAble;
import gearth.protocol.HMessage; import gearth.protocol.HMessage;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;

View File

@ -10,150 +10,151 @@ import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString; import gearth.ui.translations.TranslatableString;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.InvalidationListener; import javafx.beans.InvalidationListener;
import javafx.beans.Observable; import javafx.fxml.FXML;
import javafx.beans.binding.Bindings; import javafx.fxml.Initializable;
import javafx.event.ActionEvent;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.MouseButton; import javafx.scene.input.MouseButton;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.paint.Paint; import javafx.scene.paint.Paint;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import java.util.ArrayList; import java.net.URL;
import java.util.Arrays; import java.util.*;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
public class InjectionController extends SubForm { public class InjectionController extends SubForm implements Initializable {
private static final String HISTORY_CACHE_KEY = "INJECTED_HISTORY"; private static final String HISTORY_CACHE_KEY = "INJECTED_HISTORY";
private static final int historylimit = 69; private static final int MAX_HISTORY_ENTRIES = 69;
public TextArea inputPacket; public TextArea packetTextArea;
public Text lbl_corruption; public Text packetCorruptedText;
public Text lbl_pcktInfo; public Text packetInfoText;
public Button btn_sendToServer; public Button sendToServerButton;
public Button btn_sendToClient; public Button sendToClientButton;
public ListView<InjectedPackets> history; public ListView<InjectedPackets> historyView;
public Label lblHistory; public Label historyLabel;
public Hyperlink lnk_clearHistory; public Hyperlink clearHistoryLink;
private TranslatableString corruption, pcktInfo; private TranslatableString packetCorruptedString;
private TranslatableString packetInfoString;
@Override
protected void onParentSet() { protected void onParentSet() {
final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI); final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI);
GEarthProperties.enableDeveloperModeProperty.addListener(updateUI); GEarthProperties.enableDeveloperModeProperty.addListener(updateUI);
getHConnection().stateProperty().addListener(updateUI); getHConnection().stateProperty().addListener(updateUI);
inputPacket.textProperty().addListener(updateUI); packetTextArea.textProperty().addListener(updateUI);
} }
public void initialize() { @Override
history.setOnMouseClicked(event -> { public void initialize(URL location, ResourceBundle resources) {
if(event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) { historyView.setOnMouseClicked(event -> {
InjectedPackets injectedPackets = history.getSelectionModel().getSelectedItem(); if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
final InjectedPackets injectedPackets = historyView.getSelectionModel().getSelectedItem();
if (injectedPackets != null) { if (injectedPackets != null) {
Platform.runLater(() -> { Platform.runLater(() -> {
inputPacket.setText(injectedPackets.getPacketsAsString()); packetTextArea.setText(injectedPackets.getPacketsAsString());
updateUI(); updateUI();
}); });
} }
} }
}); });
findInjectedPackets().ifPresent(this::updateHistoryView);
List<Object> rawHistory = Cacher.getList(HISTORY_CACHE_KEY);
if (rawHistory != null) {
List<InjectedPackets> history = rawHistory.stream()
.map(o -> (String)o).limit(historylimit - 1).map(InjectedPackets::new).collect(Collectors.toList());
updateHistoryView(history);
}
initLanguageBinding(); initLanguageBinding();
} }
private static boolean isPacketIncomplete(String line) { @FXML
boolean unmatchedBrace = false; public void onClickSendToServer() {
final HPacket[] packets = parsePackets(packetTextArea.getText());
boolean ignoreBrace = false; for (HPacket packet : packets) {
getHConnection().sendToServer(packet);
for (int i = 0; i < line.length(); i++) { writeToLog(Color.BLUE, String.format("SS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId()));
if (unmatchedBrace && line.charAt(i) == '"' && line.charAt(i - 1) != '\\') { }
ignoreBrace = !ignoreBrace; addToHistory(packets, packetTextArea.getText(), HMessage.Direction.TOSERVER);
} }
if (!ignoreBrace) { @FXML
if (line.charAt(i) == '{'){ public void onClickSendToClient() {
final HPacket[] packets = parsePackets(packetTextArea.getText());
unmatchedBrace = true; for (HPacket packet : packets) {
} getHConnection().sendToClient(packet);
else if (line.charAt(i) == '}') { writeToLog(Color.RED, String.format("CS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId()));
unmatchedBrace = false;
}
} }
addToHistory(packets, packetTextArea.getText(), HMessage.Direction.TOCLIENT);
} }
return unmatchedBrace; @FXML
public void onClickClearHistory() {
Cacher.put(HISTORY_CACHE_KEY, Collections.emptyList());
updateHistoryView(Collections.emptyList());
} }
private static HPacket[] parsePackets(String fullText) { private void addToHistory(HPacket[] packets, String packetsAsString, HMessage.Direction direction) {
LinkedList<HPacket> packets = new LinkedList<>();
String[] lines = fullText.split("\n");
for (int i = 0; i < lines.length; i++) { final InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction);
String line = lines[i];
while (isPacketIncomplete(line) && i < lines.length - 1)
line += '\n' + lines[++i];
packets.add(new HPacket(line)); final List<InjectedPackets> history = Stream
.concat(
Stream.of(injectedPackets),
findInjectedPackets()
.filter(old -> !old.isEmpty() && !old.get(0).getPacketsAsString().equals(injectedPackets.getPacketsAsString()))
.orElseGet(Collections::emptyList)
.stream())
.collect(Collectors.toList());
updateHistoryView(history);
final List<String> historyAsString = history.stream().map(InjectedPackets::stringify).collect(Collectors.toList());
Cacher.put(HISTORY_CACHE_KEY, historyAsString);
} }
return packets.toArray(new HPacket[0]);
private void updateHistoryView(List<InjectedPackets> allHistoryItems) {
Platform.runLater(() -> historyView.getItems().setAll(allHistoryItems));
} }
private void updateUI() { private void updateUI() {
boolean dirty = false; boolean dirty = false;
corruption.setFormat("%s: %s"); packetCorruptedString.setFormat("%s: %s");
corruption.setKey(1, "tab.injection.corrupted.false"); packetCorruptedString.setKey(1, "tab.injection.corrupted.false");
lbl_corruption.getStyleClass().clear(); packetCorruptedText.getStyleClass().setAll("not-corrupted-label");
lbl_corruption.getStyleClass().add("not-corrupted-label");
HPacket[] packets = parsePackets(inputPacket.getText()); final HPacket[] packets = parsePackets(packetTextArea.getText());
if (packets.length == 0) { if (packets.length == 0) {
dirty = true; dirty = true;
lbl_corruption.setFill(Paint.valueOf("#ee0404b2")); packetCorruptedText.setFill(Paint.valueOf("#ee0404b2"));
lbl_corruption.getStyleClass().clear(); packetCorruptedText.getStyleClass().setAll("corrupted-label");
lbl_corruption.getStyleClass().add("corrupted-label");
} }
for (int i = 0; i < packets.length; i++) { for (int i = 0; i < packets.length; i++) {
if (packets[i].isCorrupted()) { if (packets[i].isCorrupted()) {
if (!dirty) { if (!dirty) {
corruption.setFormat("%s: %s -> " + i); packetCorruptedString.setFormat("%s: %s -> " + i);
corruption.setKey(1, "tab.injection.corrupted.true"); packetCorruptedString.setKey(1, "tab.injection.corrupted.true");
lbl_corruption.getStyleClass().clear(); packetCorruptedText.getStyleClass().setAll("corrupted-label");
lbl_corruption.getStyleClass().add("corrupted-label");
dirty = true; dirty = true;
} else } else
corruption.setFormat(corruption.getFormat() + ", " + i); packetCorruptedString.setFormat(packetCorruptedString.getFormat() + ", " + i);
} }
} }
if (dirty && packets.length == 1) { if (dirty && packets.length == 1) {
corruption.setFormatAndKeys("%s: %s", "tab.injection.corrupted", "tab.injection.corrupted.true"); packetCorruptedString.setFormatAndKeys("%s: %s", "tab.injection.corrupted", "tab.injection.corrupted.true");
} }
if (!dirty) { if (!dirty) {
HConnection connection = getHConnection(); final HConnection connection = getHConnection();
boolean canSendToClient = Arrays.stream(packets).allMatch(packet -> final boolean canSendToClient = Arrays.stream(packets).allMatch(packet ->
connection.canSendPacket(HMessage.Direction.TOCLIENT, packet)); connection.canSendPacket(HMessage.Direction.TOCLIENT, packet));
boolean canSendToServer = Arrays.stream(packets).allMatch(packet -> final boolean canSendToServer = Arrays.stream(packets).allMatch(packet ->
connection.canSendPacket(HMessage.Direction.TOSERVER, packet)); connection.canSendPacket(HMessage.Direction.TOSERVER, packet));
btn_sendToClient.setDisable(!canSendToClient); sendToClientButton.setDisable(!canSendToClient);
btn_sendToServer.setDisable(!canSendToServer); sendToServerButton.setDisable(!canSendToServer);
// mark packet sending unsafe if there is any packet that is unsafe for both TOSERVER and TOCLIENT // mark packet sending unsafe if there is any packet that is unsafe for both TOSERVER and TOCLIENT
boolean isUnsafe = Arrays.stream(packets).anyMatch(packet -> boolean isUnsafe = Arrays.stream(packets).anyMatch(packet ->
@ -163,122 +164,87 @@ public class InjectionController extends SubForm {
if (packets.length == 1) { if (packets.length == 1) {
HPacket packet = packets[0]; HPacket packet = packets[0];
if (isUnsafe) { if (isUnsafe) {
pcktInfo.setFormatAndKeys("%s (%s: " + packet.headerId() + ", %s: " + packet.length() + "), %s", packetInfoString.setFormatAndKeys("%s (%s: " + packet.headerId() + ", %s: " + packet.length() + "), %s",
"tab.injection.description.header", "tab.injection.description.header",
"tab.injection.description.id", "tab.injection.description.id",
"tab.injection.description.length", "tab.injection.description.length",
"tab.injection.description.unsafe"); "tab.injection.description.unsafe");
} } else {
else { packetInfoString.setFormatAndKeys("%s (%s: " + packet.headerId() + ", %s: " + packet.length() + ")",
pcktInfo.setFormatAndKeys("%s (%s: " + packet.headerId() + ", %s: " + packet.length() + ")",
"tab.injection.description.header", "tab.injection.description.header",
"tab.injection.description.id", "tab.injection.description.id",
"tab.injection.description.length"); "tab.injection.description.length");
} }
} } else {
else {
if (isUnsafe) { if (isUnsafe) {
pcktInfo.setFormatAndKeys("%s", "tab.injection.description.unsafe"); packetInfoString.setFormatAndKeys("%s", "tab.injection.description.unsafe");
} } else {
else { packetInfoString.setFormatAndKeys("");
pcktInfo.setFormatAndKeys("");
} }
} }
} else { } else {
if (packets.length == 1) { if (packets.length == 1) {
pcktInfo.setFormatAndKeys("%s (%s:NULL, %s: " + packets[0].getBytesLength() + ")", packetInfoString.setFormatAndKeys("%s (%s:NULL, %s: " + packets[0].getBytesLength() + ")",
"tab.injection.description.header", "tab.injection.description.header",
"tab.injection.description.id", "tab.injection.description.id",
"tab.injection.description.length"); "tab.injection.description.length");
} else {
packetInfoString.setFormatAndKeys("");
} }
else { sendToClientButton.setDisable(true);
pcktInfo.setFormatAndKeys(""); sendToServerButton.setDisable(true);
} }
btn_sendToClient.setDisable(true);
btn_sendToServer.setDisable(true);
}
}
public void sendToServer_clicked(ActionEvent actionEvent) {
HPacket[] packets = parsePackets(inputPacket.getText());
for (HPacket packet : packets) {
getHConnection().sendToServer(packet);
writeToLog(Color.BLUE, String.format("SS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId()));
}
addToHistory(packets, inputPacket.getText(), HMessage.Direction.TOSERVER);
}
public void sendToClient_clicked(ActionEvent actionEvent) {
HPacket[] packets = parsePackets(inputPacket.getText());
for (HPacket packet : packets) {
getHConnection().sendToClient(packet);
writeToLog(Color.RED, String.format("CS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId()));
}
addToHistory(packets, inputPacket.getText(), HMessage.Direction.TOCLIENT);
}
private void addToHistory(HPacket[] packets, String packetsAsString, HMessage.Direction direction) {
InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction);
List<InjectedPackets> newHistory = new ArrayList<>();
newHistory.add(injectedPackets);
List<Object> rawOldHistory = Cacher.getList(HISTORY_CACHE_KEY);
if (rawOldHistory != null) {
List<InjectedPackets> history = rawOldHistory.stream()
.map(o -> (String)o).limit(historylimit - 1).map(InjectedPackets::new).collect(Collectors.toList());
// dont add to history if its equal to the latest added packet
if (history.size() != 0 && history.get(0).getPacketsAsString().equals(injectedPackets.getPacketsAsString())) {
return;
}
newHistory.addAll(history);
}
List<String> historyAsStrings = newHistory.stream().map(InjectedPackets::stringify).collect(Collectors.toList());
Cacher.put(HISTORY_CACHE_KEY, historyAsStrings);
updateHistoryView(newHistory);
}
private void updateHistoryView(List<InjectedPackets> allHistoryItems) {
Platform.runLater(() -> {
history.getItems().clear();
history.getItems().addAll(allHistoryItems);
});
}
public void clearHistoryClick(ActionEvent actionEvent) {
Cacher.put(HISTORY_CACHE_KEY, new ArrayList<>());
updateHistoryView(new ArrayList<>());
} }
private void initLanguageBinding() { private void initLanguageBinding() {
lblHistory.textProperty().bind(new TranslatableString("%s", "tab.injection.history")); historyLabel.textProperty().bind(new TranslatableString("%s", "tab.injection.history"));
lblHistory.setTooltip(new Tooltip()); historyLabel.setTooltip(new Tooltip());
lblHistory.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.injection.history.tooltip")); historyLabel.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.injection.history.tooltip"));
corruption = new TranslatableString("%s: %s", "tab.injection.corrupted", "tab.injection.corrupted.true"); packetCorruptedString = new TranslatableString("%s: %s", "tab.injection.corrupted", "tab.injection.corrupted.true");
lbl_corruption.textProperty().bind(corruption); packetCorruptedText.textProperty().bind(packetCorruptedString);
pcktInfo = new TranslatableString("%s (%s:NULL, %s:0)", "tab.injection.description.header", "tab.injection.description.id", "tab.injection.description.length"); packetInfoString = new TranslatableString("%s (%s:NULL, %s:0)", "tab.injection.description.header", "tab.injection.description.id", "tab.injection.description.length");
lbl_pcktInfo.textProperty().bind(pcktInfo); packetInfoText.textProperty().bind(packetInfoString);
btn_sendToServer.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toserver")); sendToServerButton.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toserver"));
btn_sendToClient.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toclient")); sendToClientButton.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toclient"));
lnk_clearHistory.textProperty().bind(new TranslatableString("%s", "tab.injection.history.clear")); clearHistoryLink.textProperty().bind(new TranslatableString("%s", "tab.injection.history.clear"));
} }
public static void main(String[] args) { private static Optional<List<InjectedPackets>> findInjectedPackets() {
HPacket[] packets = parsePackets("{l}{h:3}{i:967585}{i:9589}{s:\"furni_inscriptionfuckfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\"}{s:\"sirjonasxx-II\"}{s:\"\"}{i:188}{i:0}{i:0}{b:false}"); return Optional.ofNullable(Cacher.getList(HISTORY_CACHE_KEY))
System.out.println(new HPacket("{l}{h:2550}{s:\"ClientPerf\"\"ormance\\\"}\"}{s:\"23\"}{s:\"fps\"}{s:\"Avatars: 1, Objects: 0\"}{i:76970180}").toExpression()); .map(rawList -> rawList.stream()
.limit(MAX_HISTORY_ENTRIES - 1)
.map(o -> (String) o)
.map(InjectedPackets::new)
.collect(Collectors.toList()));
}
System.out.println("hi"); private static HPacket[] parsePackets(String fullText) {
final LinkedList<HPacket> packets = new LinkedList<>();
final String[] lines = fullText.split("\n");
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
while (isPacketIncomplete(line) && i < lines.length - 1)
line += '\n' + lines[++i];
packets.add(new HPacket(line));
}
return packets.toArray(new HPacket[0]);
}
private static boolean isPacketIncomplete(String line) {
boolean unmatchedBrace = false;
boolean ignoreBrace = false;
for (int i = 0; i < line.length(); i++) {
final char c = line.charAt(i);
if (unmatchedBrace && c == '"' && line.charAt(i - 1) != '\\')
ignoreBrace = !ignoreBrace;
if (!ignoreBrace)
unmatchedBrace = c == '{' || (c != '}' && unmatchedBrace);
}
return unmatchedBrace;
} }
} }

View File

@ -20,31 +20,29 @@ import java.util.Calendar;
public class LoggerController extends SubForm { public class LoggerController extends SubForm {
public TextField txtPacketLimit; public TextField packetLimitField;
public CheckBox cbx_blockIn; public CheckBox hideIncomingPacketsBox;
public CheckBox cbx_blockOut; public CheckBox hideOutgoingPacketsBox;
public CheckBox cbx_showAdditional; public CheckBox showPacketStructureBox;
public CheckBox cbx_splitPackets; public CheckBox showAdditionalPacketInfoBox;
public CheckBox cbx_useLog; public CheckBox splitPacketsBox;
public TextFlow txt_logField; public CheckBox enableLoggingBox;
public Button btnUpdate; public TextFlow loggingField;
public CheckBox cbx_showstruct; public Button updateButton;
private int packetLimit = 8000; private int packetLimit = 8000;
private PacketLoggerFactory packetLoggerFactory;
private PacketLogger packetLogger; private PacketLogger packetLogger;
public void onParentSet(){ public void onParentSet() {
packetLoggerFactory = new PacketLoggerFactory(parentController.extensionsController.getExtensionHandler()); packetLogger = new PacketLoggerFactory(parentController.extensionsController.getExtensionHandler()).get();
packetLogger = packetLoggerFactory.get();
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(() -> { getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(() -> {
if (newState == HState.PREPARING) { if (newState == HState.PREPARING) {
miniLogText(Color.ORANGE, "Connecting to "+getHConnection().getDomain() + ":" + getHConnection().getServerPort()); miniLogText(Color.ORANGE, "Connecting to " + getHConnection().getDomain() + ":" + getHConnection().getServerPort());
} }
if (newState == HState.CONNECTED) { if (newState == HState.CONNECTED) {
miniLogText(Color.GREEN, "Connected to "+getHConnection().getDomain() + ":" + getHConnection().getServerPort()); miniLogText(Color.GREEN, "Connected to " + getHConnection().getDomain() + ":" + getHConnection().getServerPort());
packetLogger.start(getHConnection()); packetLogger.start(getHConnection());
} }
if (newState == HState.NOT_CONNECTED) { if (newState == HState.NOT_CONNECTED) {
@ -53,25 +51,30 @@ public class LoggerController extends SubForm {
} }
})); }));
getHConnection().addTrafficListener(2, message -> { Platform.runLater(() -> { getHConnection().addTrafficListener(2, message -> {
if (message.getDestination() == HMessage.Direction.TOCLIENT && cbx_blockIn.isSelected() || Platform.runLater(() -> {
message.getDestination() == HMessage.Direction.TOSERVER && cbx_blockOut.isSelected()) return; if (message.getDestination() == HMessage.Direction.TOCLIENT && hideIncomingPacketsBox.isSelected() ||
message.getDestination() == HMessage.Direction.TOSERVER && hideOutgoingPacketsBox.isSelected())
return;
if (cbx_splitPackets.isSelected()) { if (splitPacketsBox.isSelected()) {
packetLogger.appendSplitLine(); packetLogger.appendSplitLine();
} }
int types = 0; int types = 0;
if (message.getDestination() == HMessage.Direction.TOCLIENT) types |= PacketLogger.MESSAGE_TYPE.INCOMING.getValue(); if (message.getDestination() == HMessage.Direction.TOCLIENT)
else if (message.getDestination() == HMessage.Direction.TOSERVER) types |= PacketLogger.MESSAGE_TYPE.OUTGOING.getValue(); types |= PacketLogger.MESSAGE_TYPE.INCOMING.getValue();
else if (message.getDestination() == HMessage.Direction.TOSERVER)
types |= PacketLogger.MESSAGE_TYPE.OUTGOING.getValue();
if (message.getPacket().length() >= packetLimit) types |= PacketLogger.MESSAGE_TYPE.SKIPPED.getValue(); if (message.getPacket().length() >= packetLimit) types |= PacketLogger.MESSAGE_TYPE.SKIPPED.getValue();
if (message.isBlocked()) types |= PacketLogger.MESSAGE_TYPE.BLOCKED.getValue(); if (message.isBlocked()) types |= PacketLogger.MESSAGE_TYPE.BLOCKED.getValue();
if (message.getPacket().isReplaced()) types |= PacketLogger.MESSAGE_TYPE.REPLACED.getValue(); if (message.getPacket().isReplaced()) types |= PacketLogger.MESSAGE_TYPE.REPLACED.getValue();
if (cbx_showAdditional.isSelected()) types |= PacketLogger.MESSAGE_TYPE.SHOW_ADDITIONAL_DATA.getValue(); if (showAdditionalPacketInfoBox.isSelected())
types |= PacketLogger.MESSAGE_TYPE.SHOW_ADDITIONAL_DATA.getValue();
packetLogger.appendMessage(message.getPacket(), types); packetLogger.appendMessage(message.getPacket(), types);
if (cbx_showstruct.isSelected() && message.getPacket().length() < packetLimit) { if (showPacketStructureBox.isSelected() && message.getPacket().length() < packetLimit) {
packetLogger.appendStructure(message.getPacket(), message.getDestination()); packetLogger.appendStructure(message.getPacket(), message.getDestination());
} }
}); });
@ -79,49 +82,49 @@ public class LoggerController extends SubForm {
} }
public void updatePacketLimit(ActionEvent actionEvent) { public void updatePacketLimit(ActionEvent actionEvent) {
packetLimit = Integer.parseInt(txtPacketLimit.getText()); packetLimit = Integer.parseInt(packetLimitField.getText());
} }
@SuppressWarnings("Duplicates") @SuppressWarnings("Duplicates")
public void initialize() { public void initialize() {
txtPacketLimit.textProperty().addListener(observable -> { packetLimitField.textProperty().addListener(observable -> {
boolean isInt = true; boolean isInt = true;
try { try {
Integer.parseInt(txtPacketLimit.getText()); Integer.parseInt(packetLimitField.getText());
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
isInt = false; isInt = false;
} }
btnUpdate.setDisable(!isInt); updateButton.setDisable(!isInt);
}); });
txtPacketLimit.setOnKeyPressed(event -> { packetLimitField.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btnUpdate.isDisable()) { if (event.getCode().equals(KeyCode.ENTER) && !updateButton.isDisable()) {
updatePacketLimit(null); updatePacketLimit(null);
} }
}); });
} }
public void miniLogText(Color color, String text) { public void miniLogText(Color color, String text) {
if (cbx_useLog.isSelected()) { if (enableLoggingBox.isSelected()) {
String color2 = "#" + color.toString().substring(2, 8); final String color2 = "#" + color.toString().substring(2, 8);
Calendar rightNow = Calendar.getInstance(); final Calendar rightNow = Calendar.getInstance();
String hour = addToNumber(""+rightNow.get(Calendar.HOUR_OF_DAY)); final String hour = addToNumber("" + rightNow.get(Calendar.HOUR_OF_DAY));
String minutes = addToNumber(""+rightNow.get(Calendar.MINUTE)); final String minutes = addToNumber("" + rightNow.get(Calendar.MINUTE));
String seconds = addToNumber(""+rightNow.get(Calendar.SECOND)); final String seconds = addToNumber("" + rightNow.get(Calendar.SECOND));
String timestamp = "["+hour+":"+minutes+":"+seconds+"] "; String timestamp = "[" + hour + ":" + minutes + ":" + seconds + "] ";
timestamp = timestamp.replace(" ", "\u00A0"); // disable automatic linebreaks timestamp = timestamp.replace(" ", "\u00A0"); // disable automatic linebreaks
Text time = new Text(timestamp); final Text time = new Text(timestamp);
time.setStyle("-fx-opacity: "+0.5+";"); time.setStyle("-fx-opacity: " + 0.5 + ";");
text = text.replace(" ", "\u00A0"); text = text.replace(" ", "\u00A0");
Text otherText = new Text(text + "\n"); final Text otherText = new Text(text + "\n");
otherText.setStyle("-fx-fill: "+color2+";"); otherText.setStyle("-fx-fill: " + color2 + ";");
txt_logField.getChildren().addAll(time, otherText); loggingField.getChildren().addAll(time, otherText);
} }
} }
@ -129,5 +132,4 @@ public class LoggerController extends SubForm {
if (text.length() == 1) text = "0" + text; if (text.length() == 1) text = "0" + text;
return text; return text;
} }
} }

View File

@ -57,7 +57,7 @@ class LinuxTerminalLogger extends SimpleTerminalLogger {
output.append(colorizePackets.get("ENGLISH")); output.append(colorizePackets.get("ENGLISH"));
System.out.println(output.toString()); System.out.println(output);
} }
@Override @Override

View File

@ -40,12 +40,12 @@ public class ScheduleItemContainer extends GridPane {
} }
private void initialize() { private void initialize() {
RowConstraints rowConstraints = new RowConstraints(23); final RowConstraints rowConstraints = new RowConstraints(23);
getRowConstraints().addAll(rowConstraints); getRowConstraints().addAll(rowConstraints);
for (int i = 0; i < columnWidths.length; i++) { for (int columnWidth : columnWidths) {
ColumnConstraints columnConstraints = new ColumnConstraints(20); final ColumnConstraints columnConstraints = new ColumnConstraints(20);
columnConstraints.setPercentWidth(columnWidths[i]); columnConstraints.setPercentWidth(columnWidth);
getColumnConstraints().add(columnConstraints); getColumnConstraints().add(columnConstraints);
} }
@ -101,7 +101,7 @@ public class ScheduleItemContainer extends GridPane {
} }
private Label initNewLabelColumn(String text) { private Label initNewLabelColumn(String text) {
Label label = new Label(); final Label label = new Label();
// label.setMaxWidth(Double.MAX_VALUE); // label.setMaxWidth(Double.MAX_VALUE);
// label.setMinHeight(Double.MAX_VALUE); // label.setMinHeight(Double.MAX_VALUE);
// label.setAlignment(Pos.CENTER); // label.setAlignment(Pos.CENTER);

View File

@ -1,73 +1,87 @@
package gearth.ui.subforms.scheduler; package gearth.ui.subforms.scheduler;
import com.tulskiy.keymaster.common.Provider; import com.tulskiy.keymaster.common.Provider;
import gearth.extensions.parsers.HDirection;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.StateChangeListener; import gearth.protocol.HMessage;
import gearth.protocol.connection.HState; import gearth.protocol.HPacket;
import gearth.services.scheduler.Interval; import gearth.services.scheduler.Interval;
import gearth.services.scheduler.Scheduler; import gearth.services.scheduler.Scheduler;
import gearth.ui.GEarthProperties; import gearth.ui.GEarthProperties;
import gearth.ui.SubForm;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString; import gearth.ui.translations.TranslatableString;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.InvalidationListener; import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings; import javafx.fxml.FXML;
import javafx.event.ActionEvent; import javafx.fxml.Initializable;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.ui.SubForm;
import javax.swing.*; import javax.swing.*;
import java.io.*; import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.ResourceBundle;
/** /**
* Created by Jonas on 06/04/18. * Created by Jonas on 06/04/18.
*/ */
public class SchedulerController extends SubForm { public class SchedulerController extends SubForm implements Initializable {
private static final Interval defaultInterval = new Interval(0, 500); private static final Interval defaultInterval = new Interval(0, 500);
private static final HPacket defaultPacket = new HPacket("Chat", HMessage.Direction.TOCLIENT, -1, "Frank loves G-Earth", 0, 33, 0, 0); private static final HPacket defaultPacket = new HPacket("Chat", HMessage.Direction.TOCLIENT, -1, "Frank loves G-Earth", 0, 33, 0, 0);
public VBox schedulecontainer; public VBox root;
public GridPane header; public GridPane headerGrid;
public ScrollPane scrollpane; public ScrollPane scrollpane;
public Button btn_addoredit; public Button addOrEditButton;
public TextField txt_delay; public TextField packetDelayField;
public ToggleGroup scheduler_dest; public TextField packetExpressionField;
public TextField txt_packet;
public RadioButton rb_incoming;
public RadioButton rb_outgoing;
public Button btn_clear; public ToggleGroup packetTypeOptions;
public Button btn_save; public RadioButton packetIncomingOption;
public Button btn_load; public RadioButton packetOutgoingOption;
public CheckBox cbx_hotkeys; public Button clearButton;
public Button saveButton;
public Button loadButton;
public CheckBox enableHotkeysBox;
public Label
tableIndexLabel,
tablePacketLabel,
tableIntervalLabel,
tableDestinationLabel,
tableEditLabel,
packetExpressionLabel,
packetIntervalLabel;
private TranslatableString addOrEditString;
private InteractableScheduleItem isBeingEdited = null; private InteractableScheduleItem isBeingEdited = null;
private Scheduler<InteractableScheduleItem> scheduler = null; private Scheduler<InteractableScheduleItem> scheduler = null;
private TranslatableString addoredit; @Override
public Label lbl_tableIndex, lbl_tablePacket, lbl_tableInterval, lbl_tableDest, lbl_tableEdit, lbl_setupPacket, lbl_setupInterval; public void initialize(URL location, ResourceBundle resources) {
scrollpane.widthProperty().addListener(observable -> headerGrid.setPrefWidth(scrollpane.getWidth()));
packetTypeOptions.selectToggle(packetTypeOptions.getToggles().get(0));
public void initialize() { packetExpressionField.textProperty().addListener(event -> Platform.runLater(this::updateUI));
scrollpane.widthProperty().addListener(observable -> header.setPrefWidth(scrollpane.getWidth())); packetDelayField.textProperty().addListener(event -> Platform.runLater(this::updateUI));
scheduler_dest.selectToggle(scheduler_dest.getToggles().get(0));
txt_packet.textProperty().addListener(event -> Platform.runLater(this::updateUI)); clearButton.setOnAction(a -> clear());
txt_delay.textProperty().addListener(event -> Platform.runLater(this::updateUI));
//register hotkeys //register hotkeys
//disable some output things //disable some output things
@ -97,65 +111,93 @@ public class SchedulerController extends SubForm {
updateUI(); updateUI();
} }
@FXML
public void onClickAddOrEditButton() {
if (isBeingEdited == null) {
final HPacket packet = new HPacket(packetExpressionField.getText());
if (packet.isCorrupted())
return;
final InteractableScheduleItem newItem = new InteractableScheduleItem(
scheduler.size(),
false,
new Interval(packetDelayField.getText()),
packetExpressionField.getText(),
packetIncomingOption.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER);
addItem(newItem);
}
else {
isBeingEdited.getPacketAsStringProperty().set(packetExpressionField.getText());
isBeingEdited.getDelayProperty().set(new Interval(packetDelayField.getText()));
isBeingEdited.getDestinationProperty().set(packetIncomingOption.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER);
isBeingEdited.isUpdatedTrigger();
isBeingEdited = null;
setInputDefault(false);
}
}
@FXML
public void onClickSaveButton() {
final FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(LanguageBundle.get("tab.scheduler.button.save.windowtitle"));
fileChooser.getExtensionFilters().add(getExtensionFilter());
final File file = fileChooser.showSaveDialog(parentController.getStage());
if (file != null) {
final List<String> strings = new ArrayList<>();
for (int i = 0; i < scheduler.size(); i++) {
strings.add(scheduler.get(i).stringify());
if (i != scheduler.size() - 1)
strings.add("\n");
}
try {
Files.write(file.toPath(), strings);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@FXML
public void onClickLoadButton() {
final FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(LanguageBundle.get("tab.scheduler.button.load.windowtitle"));
fileChooser.getExtensionFilters().addAll(getExtensionFilter());
final File selectedFile = fileChooser.showOpenDialog(parentController.getStage());
if (selectedFile != null) {
try {
clear();
Files.readAllLines(selectedFile.toPath())
.stream()
.map(InteractableScheduleItem::new)
.forEach(this::addItem);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void switchPauseHotkey(int index) { private void switchPauseHotkey(int index) {
if (cbx_hotkeys.isSelected() && index < scheduler.size()) { if (enableHotkeysBox.isSelected() && index < scheduler.size()) {
scheduler.get(index).getPausedProperty().set(!scheduler.get(index).getPausedProperty().get()); scheduler.get(index).getPausedProperty().set(!scheduler.get(index).getPausedProperty().get());
} }
} }
public static boolean stringIsNumber(String str) {
try {
Integer.parseInt(str);
return true;
}
catch (Exception e){
return false;
}
}
private void updateUI() { private void updateUI() {
HConnection connection = getHConnection();
if (connection == null) return;
HMessage.Direction direction = rb_incoming.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER; final HConnection connection = getHConnection();
HPacket packet = new HPacket(txt_packet.getText());
boolean isPacketOk = connection.canSendPacket(direction, packet);
btn_addoredit.setDisable(!Interval.isValid(txt_delay.getText()) || !isPacketOk); if (connection == null)
} return;
public void scheduleBtnClicked(ActionEvent actionEvent) { final HMessage.Direction direction = packetIncomingOption.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER;
if (isBeingEdited == null) { final HPacket packet = new HPacket(packetExpressionField.getText());
HPacket packet = new HPacket(txt_packet.getText()); final boolean isPacketOk = connection.canSendPacket(direction, packet);
if (packet.isCorrupted()) return;
InteractableScheduleItem newItem = new InteractableScheduleItem(
scheduler.size(),
false,
new Interval(txt_delay.getText()),
txt_packet.getText(),
rb_incoming.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER);
addItem(newItem);
}
else {
isBeingEdited.getPacketAsStringProperty().set(txt_packet.getText());
isBeingEdited.getDelayProperty().set(new Interval(txt_delay.getText()));
isBeingEdited.getDestinationProperty().set(rb_incoming.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER);
isBeingEdited.isUpdatedTrigger();
isBeingEdited = null;
setInputDefault(false);
}
addOrEditButton.setDisable(!Interval.isValid(packetDelayField.getText()) || !isPacketOk);
} }
private void addItem(InteractableScheduleItem newItem) { private void addItem(InteractableScheduleItem newItem) {
new ScheduleItemContainer(newItem, schedulecontainer, scrollpane); new ScheduleItemContainer(newItem, root, scrollpane);
scheduler.add(newItem); scheduler.add(newItem);
newItem.onDelete(() -> { newItem.onDelete(() -> {
if (isBeingEdited == newItem) { if (isBeingEdited == newItem) {
setInputDefault(false); setInputDefault(false);
@ -172,13 +214,13 @@ public class SchedulerController extends SubForm {
} }
if (isBeingEdited != newItem) { if (isBeingEdited != newItem) {
txt_packet.setText(newItem.getPacketAsStringProperty().get()); packetExpressionField.setText(newItem.getPacketAsStringProperty().get());
txt_delay.setText(newItem.getDelayProperty().get().toString()); packetDelayField.setText(newItem.getDelayProperty().get().toString());
rb_incoming.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOCLIENT); packetIncomingOption.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOCLIENT);
rb_outgoing.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOSERVER); packetOutgoingOption.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOSERVER);
isBeingEdited = newItem; isBeingEdited = newItem;
addoredit.setKey(0, "tab.scheduler.button.edit"); addOrEditString.setKey(0, "tab.scheduler.button.edit");
updateUI(); updateUI();
newItem.onIsBeingUpdatedTrigger(); newItem.onIsBeingUpdatedTrigger();
} }
@ -191,127 +233,53 @@ public class SchedulerController extends SubForm {
} }
private void setInputDefault(boolean showDummyPacket) { private void setInputDefault(boolean showDummyPacket) {
txt_delay.setText(defaultInterval.toString()); packetDelayField.setText(defaultInterval.toString());
txt_packet.setText(showDummyPacket ? defaultPacket.toExpression() : ""); packetExpressionField.setText(showDummyPacket ? defaultPacket.toExpression() : "");
rb_incoming.setSelected(true); packetIncomingOption.setSelected(true);
rb_outgoing.setSelected(false); packetOutgoingOption.setSelected(false);
addoredit.setKey(0, "tab.scheduler.button.add"); addOrEditString.setKey(0, "tab.scheduler.button.add");
updateUI(); updateUI();
} }
private void clear() { private void clear() {
for (int i = scheduler.size() - 1; i >= 0; i--) { for (int i = scheduler.size() - 1; i >= 0; i--)
scheduler.get(i).delete(); scheduler.get(i).delete();
} }
}
private void load(List<InteractableScheduleItem> list) {
clear();
for (InteractableScheduleItem item : list) {
addItem(item);
}
}
public void clearBtnClicked(ActionEvent actionEvent) {
clear();
}
public void saveBtnClicked(ActionEvent actionEvent) {
FileChooser fileChooser = new FileChooser();
//Set extension filter
FileChooser.ExtensionFilter extFilter =
new FileChooser.ExtensionFilter(LanguageBundle.get("tab.scheduler.filetype"), "*.sched");
fileChooser.getExtensionFilters().add(extFilter);
fileChooser.setTitle(LanguageBundle.get("tab.scheduler.button.save.windowtitle"));
//Show save file dialog
File file = fileChooser.showSaveDialog(parentController.getStage());
if(file != null){
try {
FileWriter fileWriter = new FileWriter(file);
BufferedWriter out = new BufferedWriter(fileWriter);
for (int i = 0; i < scheduler.size(); i++) {
out.write(scheduler.get(i).stringify());
if (i != scheduler.size() - 1) out.write("\n");
}
out.flush();
out.close();
fileWriter.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void loadBtnClicked(ActionEvent actionEvent) {
List<InteractableScheduleItem> list = new ArrayList<>();
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(LanguageBundle.get("tab.scheduler.button.load.windowtitle"));
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter(LanguageBundle.get("tab.scheduler.filetype"), "*.sched"));
File selectedFile = fileChooser.showOpenDialog(parentController.getStage());
if (selectedFile != null) {
FileReader fr = null;
try {
fr = new FileReader(selectedFile);
BufferedReader br = new BufferedReader(fr);
String line = null;
while ((line = br.readLine()) != null)
{
list.add(new InteractableScheduleItem(line));
}
fr.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
load(list);
}
private void initLanguageBinding() { private void initLanguageBinding() {
addoredit = new TranslatableString("%s", "tab.scheduler.button.add"); addOrEditString = new TranslatableString("%s", "tab.scheduler.button.add");
btn_addoredit.textProperty().bind(addoredit); addOrEditButton.textProperty().bind(addOrEditString);
btn_clear.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear")); clearButton.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear"));
btn_clear.setTooltip(new Tooltip()); clearButton.setTooltip(new Tooltip());
btn_clear.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear.tooltip")); clearButton.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear.tooltip"));
btn_save.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save")); saveButton.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save"));
btn_save.setTooltip(new Tooltip()); saveButton.setTooltip(new Tooltip());
btn_save.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save.tooltip")); saveButton.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save.tooltip"));
btn_load.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load")); loadButton.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load"));
btn_load.setTooltip(new Tooltip()); loadButton.setTooltip(new Tooltip());
btn_load.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load.tooltip")); loadButton.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load.tooltip"));
lbl_tableIndex.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.index")); tableIndexLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.index"));
lbl_tablePacket.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.packet")); tablePacketLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.packet"));
lbl_tableInterval.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.interval")); tableIntervalLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.interval"));
lbl_tableDest.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.destination")); tableDestinationLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.destination"));
lbl_tableEdit.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.edit")); tableEditLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.edit"));
lbl_setupPacket.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.packet")); packetExpressionLabel.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.packet"));
lbl_setupInterval.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.interval")); packetIntervalLabel.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.interval"));
rb_incoming.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.in")); packetIncomingOption.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.in"));
rb_outgoing.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.out")); packetOutgoingOption.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.out"));
cbx_hotkeys.textProperty().bind(new TranslatableString("%s", "tab.scheduler.hotkeys")); enableHotkeysBox.textProperty().bind(new TranslatableString("%s", "tab.scheduler.hotkeys"));
}
private static FileChooser.ExtensionFilter getExtensionFilter() {
return new FileChooser.ExtensionFilter(LanguageBundle.get("tab.scheduler.filetype"), "*.sched");
} }
} }

View File

@ -1,180 +1,147 @@
package gearth.ui.subforms.tools; package gearth.ui.subforms.tools;
import gearth.services.packet_info.PacketInfoManager; import gearth.misc.BindingsUtil;
import gearth.ui.translations.TranslatableString;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;
import gearth.services.packet_info.PacketInfoManager;
import gearth.ui.SubForm; import gearth.ui.SubForm;
import gearth.ui.translations.TranslatableString;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ResourceBundle;
public class ToolsController extends SubForm implements Initializable {
public class ToolsController extends SubForm { public TextField decodedIntegerField;
public TextField txt_intDecoded; public TextField encodedIntegerField;
public TextField txt_intEncoded; public TextField decodedUShortField;
public TextField txt_ushortDecoded; public TextField encodedUShortField;
public TextField txt_ushortEncoded; public Button encodeIntegerButton;
public Button btnEncodeInt; public Button decodeIntegerButton;
public Button btnDecodeInt; public Button encodeUShortButton;
public Button btnEncodeUShort; public Button decodeUShortButton;
public Button btnDecodeUshort;
public Button btn_toExpr; public TextArea packetArea;
public TextArea txt_packetArea; public TextArea expressionArea;
public Button btn_toPacket; public Button convertPacketToExpressionButton;
public TextArea txt_exprArea; public Button convertExpressionToPacketButton;
public Label lbl_integer, lbl_uShort, lbl_encodingDecoding, lbl_packetToExpression; public Label
integerLabel,
uShortLabel,
encodingOrDecodingLabel,
packetToExpressionLabel;
//TODO: toExpression() without bytelength limit for this use only //TODO: toExpression() without bytelength limit for this use only
public void initialize() { @Override
txt_packetArea.textProperty().addListener(observable -> { public void initialize(URL location, ResourceBundle resources) {
btn_toExpr.setDisable(new HPacket(txt_packetArea.getText()).isCorrupted());
});
txt_packetArea.setOnKeyPressed(event -> { convertPacketToExpressionButton.disableProperty().bind(packetIsCorruptBinding(packetArea));
if(event.getCode().equals(KeyCode.ENTER) && !btn_toExpr.isDisable()) { convertExpressionToPacketButton.disableProperty().bind(packetIsCorruptBinding(expressionArea));
btn_toExpr_clicked(null);
}
});
txt_exprArea.textProperty().addListener(observable -> { encodeIntegerButton.disableProperty().bind(BindingsUtil.isInteger(decodedIntegerField.textProperty()).not());
btn_toPacket.setDisable(new HPacket(txt_exprArea.getText()).isCorrupted()); decodeIntegerButton.disableProperty().bind(packetLengthEqualsBinding(encodedIntegerField, Integer.BYTES).not());
});
txt_exprArea.setOnKeyPressed(event -> { encodeUShortButton.disableProperty().bind(BindingsUtil.isUShort(decodedUShortField.textProperty()).not());
if(event.getCode().equals(KeyCode.ENTER) && !btn_toPacket.isDisable()) { decodeUShortButton.disableProperty().bind(packetLengthEqualsBinding(encodedUShortField, Short.BYTES).not());
btn_toPacket_clicked(null);
}
});
fireButtonOnPressEnter(packetArea, convertPacketToExpressionButton);
txt_intDecoded.textProperty().addListener(observable -> { fireButtonOnPressEnter(expressionArea, convertExpressionToPacketButton);
boolean isInt = true; fireButtonOnPressEnter(decodedIntegerField, encodeIntegerButton);
fireButtonOnPressEnter(decodedUShortField, encodeUShortButton);
try { fireButtonOnPressEnter(encodedIntegerField, decodeIntegerButton);
Integer.parseInt(txt_intDecoded.getText()); fireButtonOnPressEnter(encodedUShortField, decodeUShortButton);
} catch (NumberFormatException e) {
isInt = false;
}
btnEncodeInt.setDisable(!isInt);
});
txt_intDecoded.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btnEncodeInt.isDisable()) {
btnEncodeInt_clicked(null);
}
});
//---------------
txt_ushortDecoded.textProperty().addListener(observable -> {
boolean isDouble = true;
try {
int res = Integer.parseInt(txt_ushortDecoded.getText());
if (res < 0 || res >= (256*256)) isDouble = false;
} catch (NumberFormatException e) {
isDouble = false;
}
btnEncodeUShort.setDisable(!isDouble);
});
txt_ushortDecoded.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btnEncodeUShort.isDisable()) {
btnEncodeUShort_clicked(null);
}
});
//----------------
txt_intEncoded.textProperty().addListener(observable -> {
HPacket packet = new HPacket(txt_intEncoded.getText());
btnDecodeInt.setDisable(packet.getBytesLength() != 4);
});
txt_intEncoded.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btnDecodeInt.isDisable()) {
btnDecodeInt_clicked(null);
}
});
//----------------
txt_ushortEncoded.textProperty().addListener(observable -> {
HPacket packet = new HPacket(txt_ushortEncoded.getText());
btnDecodeUshort.setDisable(packet.getBytesLength() != 2);
});
txt_ushortEncoded.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btnDecodeUshort.isDisable()) {
btnDecodeUshort_clicked(null);
}
});
initLanguageBinding(); initLanguageBinding();
} }
public void btnEncodeInt_clicked(ActionEvent actionEvent) { private BooleanBinding packetIsCorruptBinding(TextInputControl input) {
ByteBuffer b = ByteBuffer.allocate(4); return Bindings.createBooleanBinding(() -> new HPacket(input.getText()).isCorrupted(), input.textProperty());
b.putInt(Integer.parseInt(txt_intDecoded.getText()));
HPacket packet = new HPacket(b.array());
txt_intEncoded.setText(packet.toString());
}
public void btnDecodeInt_clicked(ActionEvent actionEvent) {
txt_intDecoded.setText(new HPacket(txt_intEncoded.getText()).readInteger(0) + "");
}
public void btnEncodeUShort_clicked(ActionEvent actionEvent) {
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(Integer.parseInt(txt_ushortDecoded.getText()));
HPacket packet = new HPacket(new byte[]{b.array()[2], b.array()[3]});
txt_ushortEncoded.setText(packet.toString());
}
public void btnDecodeUshort_clicked(ActionEvent actionEvent) {
txt_ushortDecoded.setText(new HPacket(txt_ushortEncoded.getText()).readUshort(0) + "");
} }
private BooleanBinding packetLengthEqualsBinding(TextInputControl input, int length) {
return Bindings.createBooleanBinding(() -> new HPacket(input.getText()).getBytesLength() == length, input.textProperty());
}
private void fireButtonOnPressEnter(Node node, Button button) {
node.setOnKeyPressed(event -> {
if (event.getCode().equals(KeyCode.ENTER) && !button.isDisable())
button.fire();
});
}
@FXML
public void onClickEncodeIntegerButton() {
final HPacket packet = new HPacket(ByteBuffer
.allocate(4)
.putInt(Integer.parseInt(decodedIntegerField.getText()))
.array());
encodedIntegerField.setText(packet.toString());
}
@FXML
public void onClickDecodeIntegerButton() {
final HPacket hPacket = new HPacket(encodedIntegerField.getText());
decodedIntegerField.setText(Integer.toString(hPacket.readInteger(0)));
}
@FXML
public void onClickEncodeUShortButton() {
final byte[] dst = new byte[2];
ByteBuffer
.allocate(4)
.putInt(Integer.parseInt(decodedUShortField.getText()))
.get(dst, 2, 2);
final HPacket packet = new HPacket(dst);
encodedUShortField.setText(packet.toString());
}
@FXML
public void onClickDecodeUShortButton() {
final HPacket packet = new HPacket(encodedUShortField.getText());
decodedUShortField.setText(Integer.toString(packet.readUshort(0)));
}
@FXML
public void onClickPacketToExpressionButton() {
final HPacket packet = parseToPacket(packetArea.getText());
expressionArea.setText(packet.toExpression(getHConnection().getPacketInfoManager(), true));
}
@FXML
public void onClickExpressionToPacketButton() {
final HPacket packet = parseToPacket(expressionArea.getText());
packetArea.setText(packet.toString());
}
private HPacket parseToPacket(String p) { private HPacket parseToPacket(String p) {
PacketInfoManager packetInfoManager = getHConnection().getPacketInfoManager(); final PacketInfoManager packetInfoManager = getHConnection().getPacketInfoManager();
HPacket packet = new HPacket(p); final HPacket packet = new HPacket(p);
if (!packet.isPacketComplete() && packetInfoManager != null) { if (!packet.isPacketComplete() && packetInfoManager != null)
packet.completePacket(packetInfoManager); packet.completePacket(packetInfoManager);
}
return packet; return packet;
} }
public void btn_toExpr_clicked(ActionEvent actionEvent) {
txt_exprArea.setText(parseToPacket(txt_packetArea.getText()).toExpression(getHConnection().getPacketInfoManager(), true));
}
public void btn_toPacket_clicked(ActionEvent actionEvent) {
txt_packetArea.setText(parseToPacket(txt_exprArea.getText()).toString());
}
private void initLanguageBinding() { private void initLanguageBinding() {
lbl_integer.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.integer")); integerLabel.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.integer"));
lbl_uShort.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.ushort")); uShortLabel.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.ushort"));
TranslatableString encode = new TranslatableString("%s", "tab.tools.button.encode"); final TranslatableString encode = new TranslatableString("%s", "tab.tools.button.encode");
TranslatableString decode = new TranslatableString("%s", "tab.tools.button.decode"); final TranslatableString decode = new TranslatableString("%s", "tab.tools.button.decode");
btnEncodeInt.textProperty().bind(encode); encodeIntegerButton.textProperty().bind(encode);
btnEncodeUShort.textProperty().bind(encode); encodeUShortButton.textProperty().bind(encode);
btnDecodeInt.textProperty().bind(decode); decodeIntegerButton.textProperty().bind(decode);
btnDecodeUshort.textProperty().bind(decode); decodeUShortButton.textProperty().bind(decode);
lbl_encodingDecoding.textProperty().bind(new TranslatableString("%s/%s", "tab.tools.encoding", "tab.tools.decoding")); encodingOrDecodingLabel.textProperty().bind(new TranslatableString("%s/%s", "tab.tools.encoding", "tab.tools.decoding"));
packetToExpressionLabel.textProperty().bind(new TranslatableString("%s <-> %s", "tab.tools.packet", "tab.tools.expression"));
lbl_packetToExpression.textProperty().bind(new TranslatableString("%s <-> %s", "tab.tools.packet", "tab.tools.expression"));
} }
} }

View File

@ -1,27 +1,24 @@
package gearth.ui.titlebar; package gearth.ui.titlebar;
import gearth.GEarth; import gearth.GEarth;
import gearth.misc.BindingsUtil;
import gearth.ui.GEarthProperties;
import gearth.ui.themes.ThemeFactory; import gearth.ui.themes.ThemeFactory;
import gearth.ui.translations.Language; import gearth.ui.translations.Language;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.InvalidationListener; import javafx.fxml.FXML;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.StageStyle; import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
@ -29,129 +26,127 @@ import java.util.Optional;
public class TitleBarController { public class TitleBarController {
public Label titleLabel; public Label titleLabel;
public Pane titleBar;
public ImageView titleIcon; public ImageView titleIcon;
public ImageView themeBtn; public ImageView themeButton;
public ImageView minimizeBtn; public ImageView minimizeButton;
public MenuButton languagePicker; public MenuButton languagePickerMenu;
private Stage stage; private Stage stage;
private TitleBarConfig config; private TitleBarConfig config;
private Alert alert = null; private Alert alert = null;
private double xOffset, yOffset;
private boolean isMoving = false;
public static TitleBarController create(Stage stage, TitleBarConfig config) throws IOException { public static TitleBarController create(Stage stage, TitleBarConfig config) throws IOException {
FXMLLoader loader = new FXMLLoader(TitleBarController.class.getResource("Titlebar.fxml")); final FXMLLoader loader = new FXMLLoader(TitleBarController.class.getResource("Titlebar.fxml"));
Parent titleBar = loader.load(); final Parent titleBar = loader.load();
TitleBarController controller = initNewController(loader, stage, config); final TitleBarController controller = initNewController(loader, stage, config);
VBox newParent = new VBox(titleBar, stage.getScene().getRoot()); final VBox newParent = new VBox(titleBar, stage.getScene().getRoot());
newParent.setId("titlebar-main-container"); newParent.setId("titlebar-main-container");
stage.getScene().setRoot(newParent);
stage.getScene().setRoot(newParent);
return controller; return controller;
} }
public static TitleBarController create(Alert alert) throws IOException { public static TitleBarController create(Alert alert) throws IOException {
GEarth.setAlertOwner(alert); GEarth.setAlertOwner(alert);
FXMLLoader loader = new FXMLLoader(TitleBarController.class.getResource("Titlebar.fxml")); final FXMLLoader loader = new FXMLLoader(TitleBarController.class.getResource("Titlebar.fxml"));
Parent titleBar = loader.load(); final Parent titleBar = loader.load();
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); final Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
TitleBarConfig config = new GEarthThemedTitleBarConfig(stage) { final TitleBarConfig config = new GEarthThemedTitleBarConfig(stage) {
@Override @Override
public boolean displayMinimizeButton() { public boolean displayMinimizeButton() {
return false; return false;
} }
}; };
TitleBarController controller = initNewController(loader, stage, config);
final TitleBarController controller = initNewController(loader, stage, config);
controller.alert = alert; controller.alert = alert;
Parent parent = alert.getDialogPane().getScene().getRoot();
VBox newParent = new VBox(titleBar, parent); final Parent parent = alert.getDialogPane().getScene().getRoot();
final VBox newParent = new VBox(titleBar, parent);
newParent.setId("titlebar-main-container"); newParent.setId("titlebar-main-container");
stage.setScene(new Scene(newParent)); stage.setScene(new Scene(newParent));
stage.getScene().setFill(Color.TRANSPARENT); stage.getScene().setFill(Color.TRANSPARENT);
return controller; return controller;
} }
private static TitleBarController initNewController(FXMLLoader loader, Stage stage, TitleBarConfig config) throws IOException { private static TitleBarController initNewController(FXMLLoader loader, Stage stage, TitleBarConfig config) {
TitleBarController controller = loader.getController();
controller.stage = stage;
controller.config = config;
stage.initStyle(StageStyle.TRANSPARENT); stage.initStyle(StageStyle.TRANSPARENT);
stage.titleProperty().addListener((i) -> controller.setTitle(stage.getTitle())); final TitleBarController controller = loader.getController();
controller.setTitle(stage.getTitle()); controller.stage = stage;
controller.config = config;
controller.languagePickerMenu.getItems().setAll(Language.getMenuItems());
controller.languagePickerMenu.setGraphic(LanguageBundle.getLanguage().getIcon());
controller.languagePicker.getItems().addAll(Language.getMenuItems()); BindingsUtil.setAndBind(
controller.languagePicker.setGraphic(LanguageBundle.getLanguage().getIcon()); controller.titleLabel.textProperty(),
GEarthProperties.themeTitleBinding,
true);
stage.getIcons().addListener((InvalidationListener) observable -> controller.updateIcon()); BindingsUtil.setAndBind(
controller.updateIcon(); controller.titleIcon.imageProperty(),
GEarthProperties.logoSmallImageBinding,
true);
Platform.runLater(() -> { Platform.runLater(() -> {
stage.getScene().setFill(Color.TRANSPARENT); stage.getScene().setFill(Color.TRANSPARENT);
stage.getScene().getRoot().getStyleClass().add("root-node"); stage.getScene().getRoot().getStyleClass().add("root-node");
if (!config.displayMinimizeButton()) { if (!config.displayMinimizeButton()) {
((GridPane) controller.minimizeBtn.getParent()).getChildren().remove(controller.minimizeBtn); ((GridPane) controller.minimizeButton.getParent()).getChildren().remove(controller.minimizeButton);
} }
if (!config.displayThemePicker()) { if (!config.displayThemePicker()) {
((GridPane) controller.themeBtn.getParent()).getChildren().remove(controller.themeBtn); ((GridPane) controller.themeButton.getParent()).getChildren().remove(controller.themeButton);
((GridPane) controller.languagePicker.getParent()).getChildren().remove(controller.languagePicker); ((GridPane) controller.languagePickerMenu.getParent()).getChildren().remove(controller.languagePickerMenu);
} }
}); });
return controller; return controller;
} }
private static void initLanguagePicker() { @FXML
public void onClickCloseButton() {
}
public void updateIcon() {
Platform.runLater(() -> titleIcon.setImage(stage.getIcons().size() > 0 ? stage.getIcons().get(0) :
new Image(GEarth.class.getResourceAsStream(
String.format("/gearth/ui/themes/%s/logoSmall.png", ThemeFactory.getDefaultTheme().internalName())))));
}
public void setTitle(String title) {
Platform.runLater(() -> titleLabel.setText(title));
}
public void handleCloseAction(MouseEvent event) {
config.onCloseClicked(); config.onCloseClicked();
} }
public void handleMinimizeAction(MouseEvent event) { @FXML
public void onClickMinimizeButton() {
config.onMinimizeClicked(); config.onMinimizeClicked();
} }
private double xOffset, yOffset; @FXML
private boolean isMoving = false; public void onClick(MouseEvent event) {
public void handleClickAction(MouseEvent event) {
xOffset = event.getSceneX(); xOffset = event.getSceneX();
yOffset = event.getSceneY(); yOffset = event.getSceneY();
isMoving = true; isMoving = true;
} }
public void handleMovementAction(MouseEvent event) { @FXML
public void onMovement(MouseEvent event) {
if (isMoving) { if (isMoving) {
stage.setX(event.getScreenX() - xOffset); stage.setX(event.getScreenX() - xOffset);
stage.setY(event.getScreenY() - yOffset); stage.setY(event.getScreenY() - yOffset);
} }
} }
public void handleClickReleaseAction(MouseEvent mouseEvent) { @FXML
public void onPressReleased() {
isMoving = false; isMoving = false;
} }
public void toggleTheme(MouseEvent event) { @FXML
public void toggleTheme() {
int themeIndex = ThemeFactory.allThemes().indexOf(config.getCurrentTheme()); int themeIndex = ThemeFactory.allThemes().indexOf(config.getCurrentTheme());
config.setTheme(ThemeFactory.allThemes().get((themeIndex + 1) % ThemeFactory.allThemes().size())); config.setTheme(ThemeFactory.allThemes().get((themeIndex + 1) % ThemeFactory.allThemes().size()));
} }

View File

@ -45,8 +45,8 @@
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<Label fx:id="lblInpPort" text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" /> <Label fx:id="portOptionsLabel" text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpPort" disable="true" editable="true" prefWidth="183.0" GridPane.columnIndex="1"> <ComboBox fx:id="portOptionsBox" disable="true" editable="true" prefWidth="183.0" GridPane.columnIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets right="15.0" /> <Insets right="15.0" />
</GridPane.margin> </GridPane.margin>
@ -60,8 +60,8 @@
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<Label fx:id="lblInpHost" text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" /> <Label fx:id="hostOptionsLabel" text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpHost" disable="true" editable="true" GridPane.columnIndex="1"> <ComboBox fx:id="hostOptionsBox" disable="true" editable="true" GridPane.columnIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets right="15.0" /> <Insets right="15.0" />
</GridPane.margin> </GridPane.margin>
@ -78,12 +78,12 @@
<RowConstraints /> <RowConstraints />
<RowConstraints /> <RowConstraints />
</rowConstraints> </rowConstraints>
<CheckBox fx:id="cbx_autodetect" mnemonicParsing="false" selected="true" text="Auto-detect" textAlignment="CENTER" textFill="#000000a9" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="3"> <CheckBox fx:id="autoDetectBox" mnemonicParsing="false" selected="true" text="Auto-detect" textAlignment="CENTER" textFill="#000000a9" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin> <GridPane.margin>
<Insets left="-5.0" /> <Insets left="-5.0" />
</GridPane.margin> </GridPane.margin>
</CheckBox> </CheckBox>
<Button fx:id="btnConnect" alignment="CENTER" maxWidth="1.7976931348623157E308" onAction="#btnConnect_clicked" text="Connect" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER"> <Button fx:id="connectButton" alignment="CENTER" maxWidth="1.7976931348623157E308" onAction="#onClickConnectButton" text="Connect" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets left="15.0" right="15.0" /> <Insets left="15.0" right="15.0" />
</GridPane.margin> </GridPane.margin>
@ -111,8 +111,8 @@
<RowConstraints maxHeight="86.0" minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="86.0" minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label fx:id="lblHotelVersion" text="Hotel version:" textFill="#000000cc" /> <Label fx:id="connectedHotelVersionLabel" text="Hotel version:" textFill="#000000cc" />
<TextField fx:id="txtfield_hotelversion" editable="false" prefHeight="17.0" prefWidth="285.0" GridPane.rowIndex="1"> <TextField fx:id="connectedHotelVersionField" editable="false" prefHeight="17.0" prefWidth="285.0" GridPane.rowIndex="1">
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets />
</opaqueInsets> </opaqueInsets>
@ -125,7 +125,7 @@
<Insets left="12.0" right="10.0" top="5.0" /> <Insets left="12.0" right="10.0" top="5.0" />
</GridPane.margin> </GridPane.margin>
</GridPane> </GridPane>
<GridPane fx:id="grd_clientSelection" prefHeight="26.0" prefWidth="286.0" style="-fx-border-color: #888888; -fx-border-width: 0 0 1 0;"> <GridPane fx:id="clientTypeSelectionGrid" prefHeight="26.0" prefWidth="286.0" style="-fx-border-color: #888888; -fx-border-width: 0 0 1 0;">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="76.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="76.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="25.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="25.0" />
@ -137,7 +137,7 @@
<RowConstraints minHeight="20.0" prefHeight="34.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="20.0" prefHeight="34.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label fx:id="lblClient" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="22.0" prefWidth="94.0" text="Client type:" textFill="#000000cd"> <Label fx:id="selectedClientLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="22.0" prefWidth="94.0" text="Client type:" textFill="#000000cd">
<padding> <padding>
<Insets left="8.0" /> <Insets left="8.0" />
</padding> </padding>
@ -145,20 +145,20 @@
<Insets right="-20.0" /> <Insets right="-20.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<RadioButton fx:id="rd_unity" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Unity" GridPane.columnIndex="3" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> <RadioButton fx:id="unityOption" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Unity" GridPane.columnIndex="3" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS">
<toggleGroup> <toggleGroup>
<ToggleGroup fx:id="tgl_clientMode" /> <ToggleGroup fx:id="clientTypeOptions" />
</toggleGroup> </toggleGroup>
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
</GridPane.margin> </GridPane.margin>
</RadioButton> </RadioButton>
<RadioButton fx:id="rd_flash" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="35.0" prefWidth="111.0" selected="true" text="Flash / Air" toggleGroup="$tgl_clientMode" GridPane.columnIndex="2"> <RadioButton fx:id="flashOption" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="35.0" prefWidth="111.0" selected="true" text="Flash / Air" toggleGroup="$clientTypeOptions" GridPane.columnIndex="2">
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
</GridPane.margin> </GridPane.margin>
</RadioButton> </RadioButton>
<RadioButton fx:id="rd_nitro" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="22.0" prefWidth="54.0" text="Nitro" toggleGroup="$tgl_clientMode" GridPane.columnIndex="4"> <RadioButton fx:id="nitroOption" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="22.0" prefWidth="54.0" text="Nitro" toggleGroup="$clientTypeOptions" GridPane.columnIndex="4">
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
</GridPane.margin> </GridPane.margin>
@ -196,7 +196,7 @@
<GridPane.margin> <GridPane.margin>
<Insets bottom="14.0" left="20.0" right="20.0" /> <Insets bottom="14.0" left="20.0" right="20.0" />
</GridPane.margin> </GridPane.margin>
<Label fx:id="lblStateHead" text="Connection state:" textFill="#000000ba" GridPane.valignment="BOTTOM"> <Label fx:id="connectionStateHeaderLabel" text="Connection state:" textFill="#000000ba" GridPane.valignment="BOTTOM">
<GridPane.margin> <GridPane.margin>
<Insets bottom="5.0" left="2.0" /> <Insets bottom="5.0" left="2.0" />
</GridPane.margin> </GridPane.margin>
@ -204,7 +204,7 @@
<Font size="12.0" /> <Font size="12.0" />
</font> </font>
</Label> </Label>
<Label fx:id="lblState" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-border-radius: 5px;" text="Not connected" textAlignment="CENTER" textFill="#000000d1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS"> <Label fx:id="notConnectedStateLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-border-radius: 5px;" text="Not connected" textAlignment="CENTER" textFill="#000000d1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
</GridPane.margin> </GridPane.margin>
@ -225,17 +225,17 @@
<padding> <padding>
<Insets bottom="7.0" top="7.0" /> <Insets bottom="7.0" top="7.0" />
</padding> </padding>
<Label fx:id="lblHost" text="Host:" textFill="#000000cc"> <Label fx:id="connectedHostLabel" text="Host:" textFill="#000000cc">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" /> <Insets left="10.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<Label fx:id="lblPort" text="Port:" textFill="#000000cc" GridPane.rowIndex="1"> <Label fx:id="connectedPortLabel" text="Port:" textFill="#000000cc" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" /> <Insets left="10.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<TextField fx:id="outHost" editable="false" GridPane.columnIndex="1"> <TextField fx:id="connectedHostField" editable="false" GridPane.columnIndex="1">
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets />
</opaqueInsets> </opaqueInsets>
@ -243,7 +243,7 @@
<Insets left="5.0" right="10.0" /> <Insets left="5.0" right="10.0" />
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<TextField fx:id="outPort" editable="false" GridPane.columnIndex="1" GridPane.rowIndex="1"> <TextField fx:id="connectedPortField" editable="false" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="5.0" right="10.0" /> <Insets left="5.0" right="10.0" />
</GridPane.margin> </GridPane.margin>

View File

@ -12,12 +12,12 @@
<RowConstraints maxHeight="227.0" minHeight="10.0" prefHeight="222.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="227.0" minHeight="10.0" prefHeight="222.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="185.0" minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="185.0" minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<ScrollPane fx:id="scroller" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-background: transparent; -fx-border-radius: 4px;" styleClass="table-header" vbarPolicy="ALWAYS"> <ScrollPane fx:id="contentScrollPane" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-background: transparent; -fx-border-radius: 4px;" styleClass="table-header" vbarPolicy="ALWAYS">
<GridPane.margin> <GridPane.margin>
<Insets bottom="8.0" left="17.0" right="17.0" top="17.0" /> <Insets bottom="8.0" left="17.0" right="17.0" top="17.0" />
</GridPane.margin> </GridPane.margin>
<VBox fx:id="extensioncontainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> <VBox fx:id="contentBox" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<GridPane fx:id="header_ext" gridLinesVisible="true" styleClass="table-header"> <GridPane fx:id="headerGridPane" gridLinesVisible="true" styleClass="table-header">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="22.0" prefWidth="132.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="22.0" prefWidth="132.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="34.0" prefWidth="204.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="34.0" prefWidth="204.0" />
@ -31,11 +31,11 @@
<VBox.margin> <VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" /> <Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</VBox.margin> </VBox.margin>
<Label fx:id="lbl_tableTitle" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Title" /> <Label fx:id="tableTitleLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Title" />
<Label fx:id="lbl_tableDesc" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Description" GridPane.columnIndex="1" /> <Label fx:id="tableDescriptionLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Description" GridPane.columnIndex="1" />
<Label fx:id="lbl_tableAuthor" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Author" GridPane.columnIndex="2" /> <Label fx:id="tableAuthorLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Author" GridPane.columnIndex="2" />
<Label fx:id="lbl_tableVersion" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Version" GridPane.columnIndex="3" /> <Label fx:id="tableVersionLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Version" GridPane.columnIndex="3" />
<Label fx:id="lbl_tableEdit" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" /> <Label fx:id="tableEditLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" />
</GridPane> </GridPane>
</VBox> </VBox>
</ScrollPane> </ScrollPane>
@ -61,19 +61,19 @@
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<Button fx:id="btn_gpython" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#gpythonBtnClicked" text="G-Python Shell" GridPane.columnIndex="3" /> <Button fx:id="openGPythonShellButton" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickGPythonShellButton" text="G-Python Shell" GridPane.columnIndex="3" />
<TextField fx:id="ext_port" editable="false" prefHeight="26.0" prefWidth="157.0" GridPane.columnIndex="1"> <TextField fx:id="portField" editable="false" prefHeight="26.0" prefWidth="157.0" GridPane.columnIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="-7.0" /> <Insets left="-7.0" />
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<Label fx:id="lbl_port" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Port:" textFill="#000000bb"> <Label fx:id="portLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Port:" textFill="#000000bb">
<GridPane.margin> <GridPane.margin>
<Insets left="3.0" /> <Insets left="3.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<Button fx:id="btn_install" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#installBtnClicked" text="Install" GridPane.columnIndex="5" /> <Button fx:id="installButton" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickInstallButton" text="Install" GridPane.columnIndex="5" />
<Button fx:id="btn_viewExtensionConsole" layoutX="401.0" layoutY="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#extConsoleBtnClicked" text="View logs" GridPane.columnIndex="4" /> <Button fx:id="viewLogsButton" layoutX="401.0" layoutY="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickLogsButton" text="View logs" GridPane.columnIndex="4" />
</GridPane> </GridPane>
</GridPane> </GridPane>
</GridPane> </GridPane>

View File

@ -16,10 +16,10 @@
<children> <children>
<AnchorPane prefHeight="262.0" prefWidth="318.0"> <AnchorPane prefHeight="262.0" prefWidth="318.0">
<children> <children>
<CheckBox fx:id="cbx_alwaysOnTop" layoutX="14.0" layoutY="232.0" mnemonicParsing="false" text="Always on top" /> <CheckBox fx:id="alwaysOnTopBox" layoutX="14.0" layoutY="232.0" mnemonicParsing="false" text="Always on top" />
<Hyperlink fx:id="url_troubleshooting" alignment="CENTER_RIGHT" layoutX="170.0" layoutY="232.0" prefWidth="150.0" text="Troubleshooting" /> <Hyperlink fx:id="troubleshootingLink" alignment="CENTER_RIGHT" layoutX="170.0" layoutY="232.0" prefWidth="150.0" text="Troubleshooting" />
<Label fx:id="lbl_notepad" layoutX="14.0" layoutY="8.0" text="Notepad:" textFill="#000000bd" /> <Label fx:id="notepadLabel" layoutX="14.0" layoutY="8.0" text="Notepad:" textFill="#000000bd" />
<TextArea fx:id="txtarea_notepad" layoutX="11.0" layoutY="31.0" prefHeight="197.0" prefWidth="312.0" /> <TextArea fx:id="notepadTextArea" layoutX="11.0" layoutY="31.0" prefHeight="197.0" prefWidth="312.0" />
</children> </children>
</AnchorPane> </AnchorPane>
<GridPane GridPane.columnIndex="1"> <GridPane GridPane.columnIndex="1">
@ -35,7 +35,7 @@
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="232.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="232.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<GridPane fx:id="grd_advanced" disable="true" prefHeight="161.0" prefWidth="299.0" style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="5"> <GridPane fx:id="advancedPane" disable="true" prefHeight="161.0" prefWidth="299.0" style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="5">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
@ -52,10 +52,10 @@
<Insets left="7.0" top="3.0" /> <Insets left="7.0" top="3.0" />
</padding> </padding>
<children> <children>
<CheckBox fx:id="cbx_useSocks" mnemonicParsing="false" text="Use SOCKS proxy" /> <CheckBox fx:id="advancedUseSocksBox" mnemonicParsing="false" text="Use SOCKS proxy" />
<CheckBox fx:id="cbx_disableDecryption" mnemonicParsing="false" text="Disable decryption" GridPane.rowIndex="2" /> <CheckBox fx:id="advancedDisableDecryptionBox" mnemonicParsing="false" text="Disable decryption" GridPane.rowIndex="2" />
<CheckBox fx:id="cbx_debug" mnemonicParsing="false" text="Debug to stdout" GridPane.rowIndex="3" /> <CheckBox fx:id="advancedEnableDebugBox" mnemonicParsing="false" text="Debug to stdout" GridPane.rowIndex="3" />
<GridPane fx:id="grd_socksInfo" disable="true" prefHeight="54.0" prefWidth="81.0" GridPane.rowIndex="1"> <GridPane fx:id="advancedSocksInfoGrid" disable="true" prefHeight="54.0" prefWidth="81.0" GridPane.rowIndex="1">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
@ -78,8 +78,8 @@
<RowConstraints maxHeight="2.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="2.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label fx:id="lbl_proxyIp" text="Proxy IP:" /> <Label fx:id="advancedSocksProxyIpLabel" text="Proxy IP:" />
<TextField fx:id="txt_socksIp" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="ip:port" GridPane.columnIndex="1"> <TextField fx:id="advancedSocketProxyIpField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="ip:port" GridPane.columnIndex="1">
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets />
</opaqueInsets> </opaqueInsets>
@ -96,7 +96,7 @@
</GridPane> </GridPane>
</children> </children>
</GridPane> </GridPane>
<CheckBox fx:id="cbx_advanced" mnemonicParsing="false" text="Advanced" textFill="#000000ba" GridPane.rowIndex="4"> <CheckBox fx:id="enableAdvancedBox" mnemonicParsing="false" text="Advanced" textFill="#000000ba" GridPane.rowIndex="4">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
@ -104,17 +104,17 @@
<Insets top="2.0" /> <Insets top="2.0" />
</padding> </padding>
</CheckBox> </CheckBox>
<CheckBox fx:id="cbx_gpython" mnemonicParsing="false" onAction="#gpythonCbxClick" text="G-Python scripting" textFill="#000000ba" GridPane.rowIndex="3"> <CheckBox fx:id="enableGPythonBox" mnemonicParsing="false" onAction="#onClickGPythonButton" text="G-Python scripting" textFill="#000000ba" GridPane.rowIndex="3">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
</CheckBox> </CheckBox>
<CheckBox fx:id="cbx_admin" layoutX="20.0" layoutY="25.0" mnemonicParsing="false" onAction="#adminCbxClick" selected="true" text="Client-side staff permissions" textFill="#000000ba" GridPane.rowIndex="2"> <CheckBox fx:id="enableClientSideStaffPermissionsBox" layoutX="20.0" layoutY="25.0" mnemonicParsing="false" onAction="#onClickClientSideStaffPermissionsBox" selected="true" text="Client-side staff permissions" textFill="#000000ba" GridPane.rowIndex="2">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
</CheckBox> </CheckBox>
<CheckBox fx:id="cbx_develop" layoutX="20.0" layoutY="52.0" mnemonicParsing="false" onAction="#developCbxClick" text="Developer mode" textFill="#000000ba" GridPane.rowIndex="1"> <CheckBox fx:id="enableDeveloperModeBox" layoutX="20.0" layoutY="52.0" mnemonicParsing="false" onAction="#onClickDeveloperModeBox" text="Developer mode" textFill="#000000ba" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" /> <Insets left="10.0" />
</GridPane.margin> </GridPane.margin>

View File

@ -14,18 +14,18 @@
</rowConstraints> </rowConstraints>
<AnchorPane prefHeight="200.0" prefWidth="200.0"> <AnchorPane prefHeight="200.0" prefWidth="200.0">
<children> <children>
<ImageView fx:id="img_logo" fitHeight="228.0" fitWidth="217.0" layoutX="23.0" layoutY="23.0" pickOnBounds="true" preserveRatio="true" /> <ImageView fx:id="logoImageView" fitHeight="228.0" fitWidth="217.0" layoutX="23.0" layoutY="23.0" pickOnBounds="true" preserveRatio="true" />
<Label fx:id="version" layoutX="260.0" layoutY="23.0" text="\$theme $version" textFill="#000000b2"> <Label fx:id="themeTitleLabel" layoutX="260.0" layoutY="23.0" text="\$theme $version" textFill="#000000b2">
<font> <font>
<Font size="18.0" /> <Font size="18.0" />
</font> </font>
</Label> </Label>
<Label fx:id="lbl_description" layoutX="260.0" layoutY="57.0" text="Habbo packet manipulator for Linux, Windows &amp; Mac" textFill="#000000b2"> <Label fx:id="descriptionLabel" layoutX="260.0" layoutY="57.0" text="Habbo packet manipulator for Linux, Windows &amp; Mac" textFill="#000000b2">
<font> <font>
<Font size="14.0" /> <Font size="14.0" />
</font> </font>
</Label> </Label>
<Label fx:id="lbl_createdBy" layoutX="260.0" layoutY="92.0" text="Created by:" textFill="#000000b2"> <Label fx:id="createdByLabel" layoutX="260.0" layoutY="92.0" text="Created by:" textFill="#000000b2">
<font> <font>
<Font name="System Bold" size="14.0" /> <Font name="System Bold" size="14.0" />
</font> </font>
@ -35,7 +35,7 @@
<Font size="14.0" /> <Font size="14.0" />
</font> </font>
</Label> </Label>
<Label fx:id="lbl_contrib" layoutX="260.0" layoutY="124.0" text="Contributors:" textFill="#000000b2"> <Label fx:id="contributorsLabel" layoutX="260.0" layoutY="124.0" text="Contributors:" textFill="#000000b2">
<font> <font>
<Font name="System Bold" size="14.0" /> <Font name="System Bold" size="14.0" />
</font> </font>
@ -75,18 +75,18 @@
<Font size="14.0" /> <Font size="14.0" />
</font> </font>
</Label> </Label>
<Label fx:id="lbl_links" layoutX="491.0" layoutY="92.0" text="Links:" textFill="#000000b2"> <Label fx:id="linksLabel" layoutX="491.0" layoutY="92.0" text="Links:" textFill="#000000b2">
<font> <font>
<Font name="System Bold" size="14.0" /> <Font name="System Bold" size="14.0" />
</font> </font>
</Label> </Label>
<Hyperlink fx:id="link_darkbox" layoutX="487.0" layoutY="112.0" text="Darkbox" /> <Hyperlink fx:id="darkBoxLink" layoutX="487.0" layoutY="112.0" text="Darkbox" />
<Hyperlink fx:id="link_g_gearth" layoutX="487.0" layoutY="132.0" text="Github - G-Earth" /> <Hyperlink fx:id="githubGEarthLink" layoutX="487.0" layoutY="132.0" text="Github - G-Earth" />
<Hyperlink fx:id="link_g_tanji" layoutX="487.0" layoutY="152.0" text="Github - Tanji" /> <Hyperlink fx:id="githubTanjiLink" layoutX="487.0" layoutY="152.0" text="Github - Tanji" />
<Hyperlink fx:id="link_d_gearth" layoutX="487.0" layoutY="172.0" text="Discord - G-Earth" /> <Hyperlink fx:id="discordGEarthLink" layoutX="487.0" layoutY="172.0" text="Discord - G-Earth" />
<Hyperlink fx:id="link_g_store" layoutX="487.0" layoutY="212.0" text="G-ExtensionStore" /> <Hyperlink fx:id="githubExtensionStoreLink" layoutX="487.0" layoutY="212.0" text="G-ExtensionStore" />
<Button fx:id="btn_donate" layoutX="537.0" layoutY="14.0" mnemonicParsing="false" onAction="#donate" prefHeight="20.0" prefWidth="100.0" text="Donate BTC" /> <Button fx:id="donateButton" layoutX="537.0" layoutY="14.0" mnemonicParsing="false" onAction="#donate" prefHeight="20.0" prefWidth="100.0" text="Donate BTC" />
<Hyperlink fx:id="link_t_gearth" layoutX="487.0" layoutY="192.0" text="Twitter - G-Earth" /> <Hyperlink fx:id="twitterGEarthLink" layoutX="487.0" layoutY="192.0" text="Twitter - G-Earth" />
<Label layoutX="363.0" layoutY="204.0" text="Dorving" textFill="#000000b2"> <Label layoutX="363.0" layoutY="204.0" text="Dorving" textFill="#000000b2">
<font> <font>
<Font size="14.0" /> <Font size="14.0" />

View File

@ -37,18 +37,18 @@
<GridPane.margin> <GridPane.margin>
<Insets left="13.0" right="13.0" top="4.0" /> <Insets left="13.0" right="13.0" top="4.0" />
</GridPane.margin> </GridPane.margin>
<Text fx:id="lbl_corruption" strokeType="OUTSIDE" strokeWidth="0.0" styleClass="corrupted-label" text="isCorrupted: True"> <Text fx:id="packetCorruptedText" strokeType="OUTSIDE" strokeWidth="0.0" styleClass="corrupted-label" text="isCorrupted: True">
<font> <font>
<Font name="System Italic" size="11.0" /> <Font name="System Italic" size="11.0" />
</font> </font>
</Text> </Text>
<Text fx:id="lbl_pcktInfo" fill="#000000b2" nodeOrientation="LEFT_TO_RIGHT" strokeType="OUTSIDE" strokeWidth="0.0" styleClass="pckt-info" text="header (id=NULL, length=0)" GridPane.columnIndex="1" GridPane.halignment="RIGHT"> <Text fx:id="packetInfoText" fill="#000000b2" nodeOrientation="LEFT_TO_RIGHT" strokeType="OUTSIDE" strokeWidth="0.0" styleClass="pckt-info" text="header (id=NULL, length=0)" GridPane.columnIndex="1" GridPane.halignment="RIGHT">
<font> <font>
<Font name="System Italic" size="11.0" /> <Font name="System Italic" size="11.0" />
</font> </font>
</Text> </Text>
</GridPane> </GridPane>
<TextArea fx:id="inputPacket" prefHeight="185.0" prefWidth="545.0" wrapText="true" GridPane.rowIndex="1"> <TextArea fx:id="packetTextArea" prefHeight="185.0" prefWidth="545.0" wrapText="true" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" /> <Insets bottom="5.0" left="10.0" right="10.0" />
</GridPane.margin> </GridPane.margin>
@ -61,12 +61,12 @@
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<Button fx:id="btn_sendToServer" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#sendToServer_clicked" text="Send to server" GridPane.halignment="CENTER" GridPane.valignment="CENTER"> <Button fx:id="sendToServerButton" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickSendToServer" text="Send to server" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" /> <Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<Button fx:id="btn_sendToClient" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#sendToClient_clicked" text="Send to client" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER"> <Button fx:id="sendToClientButton" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickSendToClient" text="Send to client" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" /> <Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin> </GridPane.margin>
@ -82,7 +82,7 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<ListView fx:id="history" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1" /> <ListView fx:id="historyView" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1" />
<GridPane> <GridPane>
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
@ -92,11 +92,11 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Hyperlink fx:id="lnk_clearHistory" alignment="CENTER_RIGHT" onAction="#clearHistoryClick" text="Clear" GridPane.columnIndex="1"> <Hyperlink fx:id="clearHistoryLink" alignment="CENTER_RIGHT" onAction="#onClickClearHistory" text="Clear" GridPane.columnIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets right="6.0" /> <Insets right="6.0" />
</GridPane.margin></Hyperlink> </GridPane.margin></Hyperlink>
<Label fx:id="lblHistory" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="History:" textFill="#000000cc"> <Label fx:id="historyLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="History:" textFill="#000000cc">
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
</GridPane.margin> </GridPane.margin>

View File

@ -53,13 +53,13 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
</rowConstraints> </rowConstraints>
<Label text="Packet size limit:"/> <Label text="Packet size limit:"/>
<TextField fx:id="txtPacketLimit" text="8000" GridPane.rowIndex="1"> <TextField fx:id="packetLimitField" text="8000" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets right="8.0"/> <Insets right="8.0"/>
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
</GridPane> </GridPane>
<Button fx:id="btnUpdate" alignment="CENTER" maxHeight="1.7976931348623157E308" <Button fx:id="updateButton" alignment="CENTER" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#updatePacketLimit" prefHeight="44.0" prefWidth="62.0" text="Update" onAction="#updatePacketLimit" prefHeight="44.0" prefWidth="62.0" text="Update"
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS"
@ -69,18 +69,18 @@
</GridPane.margin> </GridPane.margin>
</Button> </Button>
</GridPane> </GridPane>
<CheckBox fx:id="cbx_blockIn" mnemonicParsing="false" text="Block Incoming"/> <CheckBox fx:id="hideIncomingPacketsBox" mnemonicParsing="false" text="Block Incoming"/>
<CheckBox fx:id="cbx_blockOut" mnemonicParsing="false" text="Block Outgoing"/> <CheckBox fx:id="hideOutgoingPacketsBox" mnemonicParsing="false" text="Block Outgoing"/>
</VBox> </VBox>
<VBox alignment="BOTTOM_LEFT" prefHeight="99.0" prefWidth="198.0" spacing="8.0" GridPane.rowIndex="1"> <VBox alignment="BOTTOM_LEFT" prefHeight="99.0" prefWidth="198.0" spacing="8.0" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets/> <Insets/>
</GridPane.margin> </GridPane.margin>
<CheckBox fx:id="cbx_showAdditional" mnemonicParsing="false" selected="true" <CheckBox fx:id="showAdditionalPacketInfoBox" mnemonicParsing="false" selected="true"
text="Show additional data"/> text="Show additional data"/>
<CheckBox fx:id="cbx_showstruct" mnemonicParsing="false" selected="true" <CheckBox fx:id="showPacketStructureBox" mnemonicParsing="false" selected="true"
text="Show packet structure"/> text="Show packet structure"/>
<CheckBox fx:id="cbx_splitPackets" mnemonicParsing="false" selected="true" <CheckBox fx:id="splitPacketsBox" mnemonicParsing="false" selected="true"
text="Split packets"/> text="Split packets"/>
</VBox> </VBox>
</GridPane> </GridPane>
@ -98,7 +98,7 @@
<padding> <padding>
<Insets bottom="10.0" left="7.0" right="7.0" top="6.0"/> <Insets bottom="10.0" left="7.0" right="7.0" top="6.0"/>
</padding> </padding>
<CheckBox fx:id="cbx_useLog" mnemonicParsing="false" selected="true" text="Use history log"> <CheckBox fx:id="enableLoggingBox" mnemonicParsing="false" selected="true" text="Use history log">
<GridPane.margin> <GridPane.margin>
<Insets left="5.0"/> <Insets left="5.0"/>
</GridPane.margin> </GridPane.margin>
@ -106,7 +106,7 @@
<ScrollPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" <ScrollPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
style="-fx-border-color: #888888; -fx-border-radius: 1px; -fx-background: #FFFFFF;" style="-fx-border-color: #888888; -fx-border-radius: 1px; -fx-background: #FFFFFF;"
GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS"> GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS">
<TextFlow fx:id="txt_logField" style=" -fx-background-color: #FFFFFF;"> <TextFlow fx:id="loggingField" style=" -fx-background-color: #FFFFFF;">
<GridPane.margin> <GridPane.margin>
<Insets/> <Insets/>
</GridPane.margin> </GridPane.margin>

View File

@ -16,8 +16,8 @@
<GridPane.margin> <GridPane.margin>
<Insets bottom="8.0" left="17.0" right="17.0" top="17.0" /> <Insets bottom="8.0" left="17.0" right="17.0" top="17.0" />
</GridPane.margin> </GridPane.margin>
<VBox fx:id="schedulecontainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> <VBox fx:id="root" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<GridPane fx:id="header" gridLinesVisible="true" styleClass="table-header"> <GridPane fx:id="headerGrid" gridLinesVisible="true" styleClass="table-header">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="163.0" minWidth="10.0" percentWidth="10.0" prefWidth="57.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="163.0" minWidth="10.0" percentWidth="10.0" prefWidth="57.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="190.0" minWidth="10.0" percentWidth="39.0" prefWidth="189.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="190.0" minWidth="10.0" percentWidth="39.0" prefWidth="189.0" />
@ -31,11 +31,11 @@
<VBox.margin> <VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" /> <Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</VBox.margin> </VBox.margin>
<Label fx:id="lbl_tableIndex" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Index" /> <Label fx:id="tableIndexLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Index" />
<Label fx:id="lbl_tablePacket" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Packet" GridPane.columnIndex="1" /> <Label fx:id="tablePacketLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Packet" GridPane.columnIndex="1" />
<Label fx:id="lbl_tableInterval" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Interval" GridPane.columnIndex="2" /> <Label fx:id="tableIntervalLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Interval" GridPane.columnIndex="2" />
<Label fx:id="lbl_tableDest" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Destination" GridPane.columnIndex="3" /> <Label fx:id="tableDestinationLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Destination" GridPane.columnIndex="3" />
<Label fx:id="lbl_tableEdit" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" /> <Label fx:id="tableEditLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" />
</GridPane> </GridPane>
</VBox> </VBox>
</ScrollPane> </ScrollPane>
@ -62,19 +62,19 @@
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<TextField fx:id="txt_packet" prefHeight="25.0" prefWidth="251.0" text="[0][0][0][2][0][0]" GridPane.columnIndex="1"> <TextField fx:id="packetExpressionField" prefHeight="25.0" prefWidth="251.0" text="[0][0][0][2][0][0]" GridPane.columnIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="-7.0" /> <Insets left="-7.0" />
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<Label fx:id="lbl_setupPacket" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Packet:" textFill="#000000bb"> <Label fx:id="packetExpressionLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Packet:" textFill="#000000bb">
<GridPane.margin> <GridPane.margin>
<Insets left="3.0" /> <Insets left="3.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<Button fx:id="btn_clear" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#clearBtnClicked" text="Clear" GridPane.columnIndex="3" /> <Button fx:id="clearButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Clear" GridPane.columnIndex="3" />
<Button fx:id="btn_save" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#saveBtnClicked" text="S" GridPane.columnIndex="4" /> <Button fx:id="saveButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickSaveButton" text="S" GridPane.columnIndex="4" />
<Button fx:id="btn_load" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#loadBtnClicked" text="L" GridPane.columnIndex="5" /> <Button fx:id="loadButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickLoadButton" text="L" GridPane.columnIndex="5" />
</GridPane> </GridPane>
<GridPane prefHeight="33.0" prefWidth="502.0" GridPane.rowIndex="1"> <GridPane prefHeight="33.0" prefWidth="502.0" GridPane.rowIndex="1">
<columnConstraints> <columnConstraints>
@ -91,35 +91,35 @@
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
</GridPane.margin> </GridPane.margin>
<TextField fx:id="txt_delay" text="500+0" GridPane.columnIndex="1"> <TextField fx:id="packetDelayField" text="500+0" GridPane.columnIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets right="5.0" /> <Insets right="5.0" />
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<Label fx:id="lbl_setupInterval" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Interval:" textFill="#000000bb"> <Label fx:id="packetIntervalLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Interval:" textFill="#000000bb">
<GridPane.margin> <GridPane.margin>
<Insets left="3.0" /> <Insets left="3.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<Button fx:id="btn_addoredit" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#scheduleBtnClicked" text="Add" GridPane.columnIndex="4"> <Button fx:id="addOrEditButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickAddOrEditButton" text="Add" GridPane.columnIndex="4">
<GridPane.margin> <GridPane.margin>
<Insets bottom="2.0" left="5.0" top="2.0" /> <Insets bottom="2.0" left="5.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<RadioButton fx:id="rb_incoming" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="In" GridPane.columnIndex="2"> <RadioButton fx:id="packetIncomingOption" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="In" GridPane.columnIndex="2">
<GridPane.margin> <GridPane.margin>
<Insets left="5.0" /> <Insets left="5.0" />
</GridPane.margin> </GridPane.margin>
<toggleGroup> <toggleGroup>
<ToggleGroup fx:id="scheduler_dest" /> <ToggleGroup fx:id="packetTypeOptions" />
</toggleGroup> </toggleGroup>
</RadioButton> </RadioButton>
<RadioButton fx:id="rb_outgoing" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Out" toggleGroup="$scheduler_dest" GridPane.columnIndex="3"> <RadioButton fx:id="packetOutgoingOption" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Out" toggleGroup="$packetTypeOptions" GridPane.columnIndex="3">
<GridPane.margin> <GridPane.margin>
<Insets left="5.0" /> <Insets left="5.0" />
</GridPane.margin> </GridPane.margin>
</RadioButton> </RadioButton>
<CheckBox fx:id="cbx_hotkeys" mnemonicParsing="false" text="Enable hotkeys (Ctrl+Shift+Index)" textFill="#4d4d4d" GridPane.columnIndex="5"> <CheckBox fx:id="enableHotkeysBox" mnemonicParsing="false" text="Enable hotkeys (Ctrl+Shift+Index)" textFill="#4d4d4d" GridPane.columnIndex="5">
<GridPane.margin> <GridPane.margin>
<Insets left="32.0" /> <Insets left="32.0" />
</GridPane.margin> </GridPane.margin>

View File

@ -46,69 +46,69 @@
<GridPane.margin> <GridPane.margin>
<Insets/> <Insets/>
</GridPane.margin> </GridPane.margin>
<Label fx:id="lbl_integer" alignment="CENTER" text="Integer:"> <Label fx:id="integerLabel" alignment="CENTER" text="Integer:">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0"/> <Insets left="10.0"/>
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<TextField fx:id="txt_intDecoded" maxHeight="1.7976931348623157E308" <TextField fx:id="decodedIntegerField" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS"> maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<Button fx:id="btnEncodeInt" disable="true" maxHeight="1.7976931348623157E308" <Button fx:id="encodeIntegerButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btnEncodeInt_clicked" text="Encode" GridPane.columnIndex="2" onAction="#onClickEncodeIntegerButton" text="Encode" GridPane.columnIndex="2"
GridPane.halignment="CENTER"> GridPane.halignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<Button fx:id="btnDecodeInt" disable="true" maxHeight="1.7976931348623157E308" <Button fx:id="decodeIntegerButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btnDecodeInt_clicked" text="Decode" GridPane.columnIndex="3" onAction="#onClickDecodeIntegerButton" text="Decode" GridPane.columnIndex="3"
GridPane.halignment="CENTER"> GridPane.halignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<TextField fx:id="txt_intEncoded" maxHeight="1.7976931348623157E308" <TextField fx:id="encodedIntegerField" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" GridPane.columnIndex="4"> maxWidth="1.7976931348623157E308" GridPane.columnIndex="4">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<Label fx:id="lbl_uShort" alignment="CENTER" text="Ushort:" GridPane.rowIndex="1"> <Label fx:id="uShortLabel" alignment="CENTER" text="Ushort:" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0"/> <Insets left="10.0"/>
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<TextField fx:id="txt_ushortDecoded" maxHeight="1.7976931348623157E308" <TextField fx:id="decodedUShortField" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS"
GridPane.rowIndex="1"> GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</TextField> </TextField>
<Button fx:id="btnEncodeUShort" disable="true" maxHeight="1.7976931348623157E308" <Button fx:id="encodeUShortButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btnEncodeUShort_clicked" text="Encode" GridPane.columnIndex="2" onAction="#onClickEncodeUShortButton" text="Encode" GridPane.columnIndex="2"
GridPane.halignment="CENTER" GridPane.rowIndex="1"> GridPane.halignment="CENTER" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<Button fx:id="btnDecodeUshort" disable="true" maxHeight="1.7976931348623157E308" <Button fx:id="decodeUShortButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btnDecodeUshort_clicked" text="Decode" GridPane.columnIndex="3" onAction="#onClickDecodeUShortButton" text="Decode" GridPane.columnIndex="3"
GridPane.halignment="CENTER" GridPane.rowIndex="1"> GridPane.halignment="CENTER" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<TextField fx:id="txt_ushortEncoded" maxHeight="1.7976931348623157E308" <TextField fx:id="encodedUShortField" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" GridPane.columnIndex="4" GridPane.rowIndex="1"> maxWidth="1.7976931348623157E308" GridPane.columnIndex="4" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
@ -116,7 +116,7 @@
</TextField> </TextField>
</GridPane> </GridPane>
<Label fx:id="lbl_encodingDecoding" text="Encoding/Decoding" textFill="#000000cc"> <Label fx:id="encodingOrDecodingLabel" text="Encoding/Decoding" textFill="#000000cc">
<GridPane.margin> <GridPane.margin>
<Insets left="6.0" top="5.0"/> <Insets left="6.0" top="5.0"/>
</GridPane.margin> </GridPane.margin>
@ -149,29 +149,29 @@
<GridPane.margin> <GridPane.margin>
<Insets/> <Insets/>
</GridPane.margin> </GridPane.margin>
<Button fx:id="btn_toExpr" disable="true" maxHeight="1.7976931348623157E308" <Button fx:id="convertPacketToExpressionButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btn_toExpr_clicked" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickPacketToExpressionButton"
text="------&gt;" GridPane.columnIndex="1" GridPane.halignment="CENTER"> text="------&gt;" GridPane.columnIndex="1" GridPane.halignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<TextArea fx:id="txt_packetArea" maxHeight="1.7976931348623157E308" <TextArea fx:id="packetArea" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true"
GridPane.halignment="CENTER"> GridPane.halignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="7.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="7.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</TextArea> </TextArea>
<Button fx:id="btn_toPacket" disable="true" maxHeight="1.7976931348623157E308" <Button fx:id="convertExpressionToPacketButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btn_toPacket_clicked" text="&lt;------" GridPane.columnIndex="2" onAction="#onClickExpressionToPacketButton" text="&lt;------" GridPane.columnIndex="2"
GridPane.halignment="CENTER"> GridPane.halignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/> <Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin> </GridPane.margin>
</Button> </Button>
<TextArea fx:id="txt_exprArea" maxHeight="1.7976931348623157E308" <TextArea fx:id="expressionArea" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true"
GridPane.columnIndex="3" GridPane.halignment="CENTER"> GridPane.columnIndex="3" GridPane.halignment="CENTER">
<GridPane.margin> <GridPane.margin>
@ -179,7 +179,7 @@
</GridPane.margin> </GridPane.margin>
</TextArea> </TextArea>
</GridPane> </GridPane>
<Label fx:id="lbl_packetToExpression" text="Packet &lt;-&gt; Expression" textFill="#000000cc"> <Label fx:id="packetToExpressionLabel" text="Packet &lt;-&gt; Expression" textFill="#000000cc">
<GridPane.margin> <GridPane.margin>
<Insets left="6.0" top="2.0"/> <Insets left="6.0" top="2.0"/>
</GridPane.margin> </GridPane.margin>

View File

@ -15,17 +15,17 @@
<RowConstraints maxHeight="25.0" minHeight="25.0" prefHeight="25.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="25.0" minHeight="25.0" prefHeight="25.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<ImageView id="minimize-button" fx:id="minimizeBtn" fitHeight="25.0" fitWidth="50.0" onMouseClicked="#handleMinimizeAction" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1"> <ImageView id="minimize-button" fx:id="minimizeButton" fitHeight="25.0" fitWidth="50.0" onMouseClicked="#onClickMinimizeButton" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1">
<image> <image>
<Image url="@files/minimizeButton.png" /> <Image url="@files/minimizeButton.png" />
</image> </image>
</ImageView> </ImageView>
<ImageView id="close-button" fitHeight="25.0" fitWidth="50.0" onMouseClicked="#handleCloseAction" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2"> <ImageView id="close-button" fitHeight="25.0" fitWidth="50.0" onMouseClicked="#onClickCloseButton" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2">
<image> <image>
<Image url="@files/closeButton.png" /> <Image url="@files/closeButton.png" />
</image> </image>
</ImageView> </ImageView>
<GridPane maxHeight="25.0" maxWidth="1.7976931348623157E308" minHeight="25.0" minWidth="-Infinity" onMouseDragged="#handleMovementAction" onMousePressed="#handleClickAction" onMouseReleased="#handleClickReleaseAction" prefHeight="25.0"> <GridPane maxHeight="25.0" maxWidth="1.7976931348623157E308" minHeight="25.0" minWidth="-Infinity" onMouseDragged="#onMovement" onMousePressed="#onClick" onMouseReleased="#onPressReleased" prefHeight="25.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="7.0" minWidth="7.0" prefWidth="7.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="7.0" minWidth="7.0" prefWidth="7.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" />
@ -48,11 +48,11 @@
<Insets left="2.0" /> <Insets left="2.0" />
</padding> </padding>
</Label> </Label>
<MenuButton id="language-picker" fx:id="languagePicker" alignment="CENTER" contentDisplay="CENTER" graphicTextGap="0.0" mnemonicParsing="false" translateX="-5.0" GridPane.columnIndex="3"> <MenuButton id="language-picker" fx:id="languagePickerMenu" alignment="CENTER" contentDisplay="CENTER" graphicTextGap="0.0" mnemonicParsing="false" translateX="-5.0" GridPane.columnIndex="3">
<items> <items>
</items> </items>
</MenuButton> </MenuButton>
<ImageView id="theme-button" fx:id="themeBtn" fitHeight="20.0" fitWidth="38.0" onMouseClicked="#toggleTheme" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="4"> <ImageView id="theme-button" fx:id="themeButton" fitHeight="20.0" fitWidth="38.0" onMouseClicked="#toggleTheme" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="4">
<image> <image>
<Image url="@../themes/G-Earth/themeButton.png" /> <Image url="@../themes/G-Earth/themeButton.png" />
</image> </image>