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;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.util.StringConverter;
import java.util.function.Function;
/**
* Provides utility methods for bindings.
*
@ -14,6 +19,27 @@ import javafx.util.StringConverter;
*/
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.
*/
@ -25,6 +51,20 @@ public final class BindingsUtil {
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.
*/

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;
import gearth.ui.subforms.scheduler.SchedulerController;
import gearth.misc.StringUtils;
/**
* Created by Jonas on 11/04/18.
@ -23,7 +23,7 @@ public class Interval {
offset = -1;
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;
offset = -1;
return;

View File

@ -1,31 +1,41 @@
package gearth.ui.buttons;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import java.io.File;
import java.util.Objects;
public class BoxButton extends StackPane {
private ImageView imageView;
private Image image;
private Image imageOnHover;
private final ImageView imageView;
private final Image image;
private final Image imageOnHover;
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) {
this.image = new Image(getClass().getResourceAsStream("files/" + imageName));
this.imageOnHover = new Image(getClass().getResourceAsStream("files/" + imageOnHoverName));
this.image = getImageResource(imageName);
this.imageOnHover = getImageResource(imageOnHoverName);
this.imageView = new ImageView();
setCursor(Cursor.DEFAULT);
getChildren().add(imageView);
setOnMouseEntered(onMouseHover);
setOnMouseExited(onMouseHoverDone);
setOnMouseEntered(t -> {
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() {
@ -37,19 +47,4 @@ public class BoxButton extends StackPane {
imageView.setImage(null);
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.
*/
public class ExitButton extends BoxButton {
public ExitButton() {
super("ButtonExit.png", "ButtonExitHover.png");
}

View File

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

View File

@ -10,45 +10,55 @@ import javafx.scene.layout.StackPane;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Created by Jonas on 11/04/18.
*/
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 Image imagePause;
private Image imagePauseOnHover;
private Image imageResume;
private Image imageResumeOnHover;
private final Image imageResume;
private final Image imageResumeOnHover;
private volatile boolean isHovering = false;
private List<InvalidationListener> clickListeners = new ArrayList<>();
private final List<InvalidationListener> clickListeners = new ArrayList<>();
public PauseResumeButton(boolean isPaused) {
this.isPaused[0] = isPaused;
this.imagePause = new Image(getClass().getResourceAsStream("files/ButtonPause.png"));
this.imagePauseOnHover = new Image(getClass().getResourceAsStream("files/ButtonPauseHover.png"));
this.imageResume = new Image(getClass().getResourceAsStream("files/ButtonResume.png"));
this.imageResumeOnHover = new Image(getClass().getResourceAsStream("files/ButtonResumeHover.png"));
this.imagePause = getImageResource("files/ButtonPause.png");
this.imagePauseOnHover = getImageResource("files/ButtonPauseHover.png");
this.imageResume = getImageResource("files/ButtonResume.png");
this.imageResumeOnHover = getImageResource("files/ButtonResumeHover.png");
this.imageView = new ImageView();
setCursor(Cursor.DEFAULT);
getChildren().add(imageView);
setOnMouseEntered(onMouseHover);
setOnMouseExited(onMouseHoverDone);
setOnMouseEntered( t -> {
imageView.setImage(isPaused() ? imageResumeOnHover : imagePauseOnHover);
isHovering = true;
});
setOnMouseExited(t -> {
imageView.setImage(isPaused() ? imageResume : imagePause);
isHovering = false;
});
imageView.setImage(isPaused() ? imageResume : imagePause);
setEventHandler(MouseEvent.MOUSE_CLICKED, event -> click());
}
private Image getImageResource(String name) {
return new Image(Objects.requireNonNull(getClass().getResourceAsStream(name)));
}
public boolean isPaused() {
return isPaused[0];
}
@ -57,24 +67,8 @@ public class PauseResumeButton extends StackPane{
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) {
isPaused[0] = paused;
imageView.setImage(isPaused() ?
(isHovering ? imageResumeOnHover : imageResume) :
(isHovering ? imagePauseOnHover : imagePause)
@ -86,22 +80,4 @@ public class PauseResumeButton extends StackPane{
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.
*/
public class ReloadButton extends BoxButton {
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.services.Constants;
import gearth.ui.GEarthProperties;
import gearth.ui.SubForm;
import gearth.ui.translations.TranslatableString;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import gearth.ui.SubForm;
import javafx.scene.layout.GridPane;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionController extends SubForm {
public ComboBox<String> inpPort;
public ComboBox<String> inpHost;
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;
public ComboBox<String> portOptionsBox;
public ComboBox<String> hostOptionsBox;
private final Object lock = new Object();
private volatile int fullyInitialized = 0;
public Button connectButton;
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 RadioButton rd_unity;
public RadioButton rd_flash;
public RadioButton rd_nitro;
public GridPane grd_clientSelection;
public GridPane clientTypeSelectionGrid;
public ToggleGroup clientTypeOptions;
public RadioButton unityOption;
public RadioButton flashOption;
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;
public void initialize() {
Constants.UNITY_PACKETS = rd_unity.isSelected();
tgl_clientMode.selectedToggleProperty().addListener(observable -> {
Constants.UNITY_PACKETS = unityOption.isSelected();
clientTypeOptions.selectedToggleProperty().addListener(observable -> {
changeClientMode();
Constants.UNITY_PACKETS = rd_unity.isSelected();
Constants.UNITY_PACKETS = unityOption.isSelected();
});
GEarthProperties.clientTypeProperty
.addListener((observable, oldValue, newValue) -> selectClientType(newValue));
selectClientType(GEarthProperties.clientTypeProperty.getValue());
cbx_autodetect.selectedProperty().addListener(observable -> updateInputUI());
inpPort.getEditor().textProperty().addListener(observable -> updateInputUI());
autoDetectBox.selectedProperty().addListener(observable -> updateInputUI());
portOptionsBox.getEditor().textProperty().addListener(observable -> updateInputUI());
BindingsUtil.setAndBindBiDirectional(cbx_autodetect.selectedProperty(), GEarthProperties.autoDetectProperty);
BindingsUtil.setAndBindBiDirectional(outHost.textProperty(), GEarthProperties.hostProperty);
BindingsUtil.setAndBindBiDirectional(outPort.textProperty(), GEarthProperties.portProperty);
BindingsUtil.setAndBindBiDirectional(autoDetectBox.selectedProperty(), GEarthProperties.autoDetectProperty);
BindingsUtil.setAndBindBiDirectional(connectedHostField.textProperty(), GEarthProperties.hostProperty);
BindingsUtil.setAndBindBiDirectional(connectedPortField.textProperty(), GEarthProperties.portProperty);
List<String> knownHosts = ProxyProviderFactory.autoDetectHosts;
Set<String> hosts = new HashSet<>();
Set<String> ports = new HashSet<>();
initHostSelection();
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) {
String[] split = h.split(":");
@ -92,228 +287,30 @@ public class ConnectionController extends SubForm {
}
inpPort.getItems().addAll(portsSorted);
inpHost.getItems().addAll(hostsSorted);
portOptionsBox.getItems().addAll(portsSorted);
hostOptionsBox.getItems().addAll(hostsSorted);
inpPort.getSelectionModel().select(portSelectIndex);
inpHost.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;
portOptionsBox.getSelectionModel().select(portSelectIndex);
hostOptionsBox.getSelectionModel().select(hostSelectIndex);
}
private void initLanguageBinding() {
TranslatableString port = new TranslatableString("%s", "tab.connection.port");
TranslatableString host = new TranslatableString("%s", "tab.connection.host");
lblInpPort.textProperty().bind(port);
lblInpHost.textProperty().bind(host);
lblPort.textProperty().bind(port);
lblHost.textProperty().bind(host);
cbx_autodetect.textProperty().bind(new TranslatableString("%s", "tab.connection.autodetect"));
portOptionsLabel.textProperty().bind(port);
hostOptionsLabel.textProperty().bind(host);
connectedPortLabel.textProperty().bind(port);
connectedHostLabel.textProperty().bind(host);
autoDetectBox.textProperty().bind(new TranslatableString("%s", "tab.connection.autodetect"));
connect = new TranslatableString("%s", "tab.connection.button.connect");
btnConnect.textProperty().bind(connect);
lblHotelVersion.textProperty().bind(new TranslatableString("%s", "tab.connection.version"));
lblClient.textProperty().bind(new TranslatableString("%s", "tab.connection.client"));
rd_unity.textProperty().bind(new TranslatableString("%s", "tab.connection.client.unity"));
rd_flash.textProperty().bind(new TranslatableString("%s", "tab.connection.client.flash"));
rd_nitro.textProperty().bind(new TranslatableString("%s", "tab.connection.client.nitro"));
lblStateHead.textProperty().bind(new TranslatableString("%s", "tab.connection.state"));
connectButton.textProperty().bind(connect);
connectedHotelVersionLabel.textProperty().bind(new TranslatableString("%s", "tab.connection.version"));
selectedClientLabel.textProperty().bind(new TranslatableString("%s", "tab.connection.client"));
unityOption.textProperty().bind(new TranslatableString("%s", "tab.connection.client.unity"));
flashOption.textProperty().bind(new TranslatableString("%s", "tab.connection.client.flash"));
nitroOption.textProperty().bind(new TranslatableString("%s", "tab.connection.client.nitro"));
connectionStateHeaderLabel.textProperty().bind(new TranslatableString("%s", "tab.connection.state"));
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 {
private VBox parent;
private ScrollPane scrollPane;
private final VBox parent;
private final ScrollPane scrollPane;
private final Object lock = new Object();
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.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.NetworkExtensionServer;
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.ExtensionRunnerFactory;
@ -14,52 +14,68 @@ import gearth.ui.subforms.extensions.logger.ExtensionLogger;
import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.fxml.FXML;
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.VBox;
import javafx.stage.FileChooser;
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.
*/
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 TextField ext_port;
public VBox extensioncontainer;
public GridPane header_ext;
public ScrollPane scroller;
public Button btn_viewExtensionConsole;
public Button btn_gpython;
public Button viewLogsButton;
public Button openGPythonShellButton;
public Label
tableTitleLabel,
tableDescriptionLabel,
tableAuthorLabel,
tableVersionLabel,
tableEditLabel,
portLabel;
private ExtensionRunner extensionRunner = null;
private ExtensionHandler extensionHandler;
private NetworkExtensionServer networkExtensionsProducer; // needed for port
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);
public void initialize() {
scroller.widthProperty().addListener(observable -> header_ext.setPrefWidth(scroller.getWidth()));
@Override
public void initialize(URL location, ResourceBundle resources) {
extensionLogger = new ExtensionLogger();
btn_install.disableProperty().bind(GEarthProperties.enableDeveloperModeProperty.not());
headerGridPane.prefWidthProperty().bind(contentScrollPane.widthProperty());
installButton.disableProperty().bind(GEarthProperties.enableDeveloperModeProperty.not());
initLanguageBinding();
}
@Override
protected void onParentSet() {
ExtensionItemContainerProducer producer = new ExtensionItemContainerProducer(extensioncontainer, scroller);
ExtensionItemContainerProducer producer = new ExtensionItemContainerProducer(contentBox, contentScrollPane);
extensionHandler = new ExtensionHandler(getHConnection());
extensionHandler.getObservable().addListener((e -> {
Platform.runLater(() -> producer.extensionConnected(e));
}));
extensionHandler.getObservable().addListener((e -> Platform.runLater(() -> producer.extensionConnected(e))));
//noinspection OptionalGetWithoutIsPresent
networkExtensionsProducer
@ -67,42 +83,20 @@ public class ExtensionsController extends SubForm {
.filter(producer1 -> producer1 instanceof NetworkExtensionServer)
.findFirst().get();
producer.setPort(networkExtensionsProducer.getPort());
ext_port.setText(networkExtensionsProducer.getPort()+"");
// System.out.println("Extension server registered on port: " + extensionsRegistrer.getPort());
portField.setText(Integer.toString(networkExtensionsProducer.getPort()));
extensionRunner = ExtensionRunnerFactory.get();
extensionRunner.runAllExtensions(networkExtensionsProducer.getPort());
extensionHandler.getObservable().addListener(e -> e.getExtensionObservable().addListener(new ExtensionListener() {
extensionHandler.getObservable().addListener(e ->
e.getExtensionObservable().addListener(new ExtensionListener() {
@Override
public void log(String 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
@ -110,47 +104,63 @@ public class ExtensionsController extends SubForm {
updateGPythonStatus();
}
public void updateGPythonStatus() {
if (!pythonShellLaunching) {
btn_gpython.setDisable(!parentController.extraController.useGPython());
}
@FXML
public void onClickInstallButton() {
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) {
btn_install.setDisable(!enabled);
@FXML
public void onClickLogsButton() {
if (!extensionLogger.isVisible())
extensionLogger.show();
else
extensionLogger.hide();
}
private volatile int gpytonShellCounter = 1;
private volatile boolean pythonShellLaunching = false;
public void gpythonBtnClicked(ActionEvent actionEvent) {
pythonShellLaunching = true;
Platform.runLater(() -> btn_gpython.setDisable(true));
@FXML
public void onClickGPythonShellButton() {
pythonShellLaunching.set(true);
Platform.runLater(() -> openGPythonShellButton.setDisable(true));
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(),
NetworkExtensionAuthenticator.generatePermanentCookie()
);
shell.launch((b) -> {
pythonShellLaunching = false;
pythonShellLaunching.set(false);
Platform.runLater(this::updateGPythonStatus);
});
}
public void updateGPythonStatus() {
if (!pythonShellLaunching.get())
openGPythonShellButton.setDisable(!parentController.extraController.useGPython());
}
public ExtensionHandler getExtensionHandler() {
return extensionHandler;
}
private void initLanguageBinding() {
lbl_tableTitle.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.title"));
lbl_tableDesc.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.description"));
lbl_tableAuthor.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.author"));
lbl_tableVersion.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.version"));
lbl_tableEdit.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.edit"));
tableTitleLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.title"));
tableDescriptionLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.description"));
tableAuthorLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.author"));
tableVersionLabel.textProperty().bind(new TranslatableString("%s", "tab.extensions.table.version"));
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"));
btn_viewExtensionConsole.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.logs"));
btn_install.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.install"));
openGPythonShellButton.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.pythonshell"));
viewLogsButton.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.logs"));
installButton.textProperty().bind(new TranslatableString("%s", "tab.extensions.button.install"));
}
}

View File

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

View File

@ -1,5 +1,6 @@
package gearth.ui.subforms.extensions.logger;
import gearth.misc.StringUtils;
import javafx.application.Platform;
import javafx.fxml.Initializable;
import javafx.scene.layout.BorderPane;
@ -12,15 +13,14 @@ import java.net.URL;
import java.util.*;
public class ExtensionLoggerController implements Initializable {
public BorderPane borderPane;
private Stage stage = null;
private StyleClassedTextArea area;
private volatile boolean initialized = false;
private final List<Element> appendOnLoad = new ArrayList<>();
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
area = new StyleClassedTextArea();
@ -44,8 +44,8 @@ public class ExtensionLoggerController implements Initializable {
private synchronized void appendLog(List<Element> elements) {
Platform.runLater(() -> {
StringBuilder sb = new StringBuilder();
StyleSpansBuilder<Collection<String>> styleSpansBuilder = new StyleSpansBuilder<>(0);
final StringBuilder sb = new StringBuilder();
final StyleSpansBuilder<Collection<String>> styleSpansBuilder = new StyleSpansBuilder<>(0);
for (Element element : elements) {
sb.append(element.text);
@ -66,7 +66,7 @@ public class ExtensionLoggerController implements Initializable {
}
void log(String s) {
s = cleanTextContent(s);
s = StringUtils.cleanTextContent(s);
ArrayList<Element> elements = new ArrayList<>();
String classname, text;
@ -98,21 +98,6 @@ public class ExtensionLoggerController implements Initializable {
}
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.misc.BindingsUtil;
import gearth.misc.HyperLinkUtil;
import gearth.protocol.connection.HState;
import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.SocksConfiguration;
@ -9,79 +10,82 @@ import gearth.services.always_admin.AdminService;
import gearth.services.g_python.GPythonVersionUtils;
import gearth.ui.GEarthProperties;
import gearth.ui.SubForm;
import gearth.ui.subforms.info.InfoController;
import gearth.ui.titlebar.TitleBarController;
import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import java.io.IOException;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
/**
* 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 TextArea notepadTextArea;
public TextArea txtarea_notepad;
public CheckBox alwaysOnTopBox;
public Hyperlink troubleshootingLink;
public CheckBox cbx_alwaysOnTop;
public Hyperlink url_troubleshooting;
public CheckBox enableClientSideStaffPermissionsBox;
public CheckBox enableDeveloperModeBox;
//TODO add setup link to g-earth wiki
public CheckBox cbx_gpython;
public CheckBox enableGPythonBox;
public CheckBox enableAdvancedBox;
public CheckBox cbx_advanced;
public GridPane grd_advanced;
public GridPane advancedPane;
public CheckBox advancedDisableDecryptionBox;
public CheckBox advancedEnableDebugBox;
public CheckBox advancedUseSocksBox;
public GridPane advancedSocksInfoGrid;
public TextField advancedSocketProxyIpField;
public CheckBox cbx_disableDecryption;
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;
public Label notepadLabel, advancedSocksProxyIpLabel;
private AdminService adminService;
public void initialize() {
url_troubleshooting.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting"));
InfoController.activateHyperlink(url_troubleshooting);
@Override
public void initialize(URL location, ResourceBundle resources) {
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());
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(notepadTextArea.textProperty(), GEarthProperties.notesProperty);
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);
BindingsUtil.setAndBindBiDirectional(cbx_debug.selectedProperty(), GEarthProperties.enableDebugProperty);
BindingsUtil.setAndBindBiDirectional(cbx_disableDecryption.selectedProperty(), GEarthProperties.disablePacketDecryptionProperty);
BindingsUtil.setAndBindBiDirectional(cbx_alwaysOnTop.selectedProperty(), GEarthProperties.alwaysOnTopProperty);
BindingsUtil.setAndBindBiDirectional(cbx_develop.selectedProperty(), GEarthProperties.enableDeveloperModeProperty);
BindingsUtil.setAndBindBiDirectional(cbx_admin.selectedProperty(), GEarthProperties.alwaysAdminProperty);
BindingsUtil.setAndBindBiDirectional(cbx_gpython.selectedProperty(), GEarthProperties.enableGPythonProperty);
BindingsUtil.setAndBindBiDirectional(advancedEnableDebugBox.selectedProperty(), GEarthProperties.enableDebugProperty);
BindingsUtil.setAndBindBiDirectional(advancedDisableDecryptionBox.selectedProperty(), GEarthProperties.disablePacketDecryptionProperty);
BindingsUtil.setAndBindBiDirectional(alwaysOnTopBox.selectedProperty(), GEarthProperties.alwaysOnTopProperty);
BindingsUtil.setAndBindBiDirectional(enableDeveloperModeBox.selectedProperty(), GEarthProperties.enableDeveloperModeProperty);
BindingsUtil.setAndBindBiDirectional(enableClientSideStaffPermissionsBox.selectedProperty(), GEarthProperties.alwaysAdminProperty);
BindingsUtil.setAndBindBiDirectional(enableGPythonBox.selectedProperty(), GEarthProperties.enableGPythonProperty);
initLanguageBinding();
}
@Override
protected void onParentSet() {
adminService = new AdminService(cbx_admin.isSelected(), getHConnection());
adminService = new AdminService(enableClientSideStaffPermissionsBox.isSelected(), getHConnection());
getHConnection().addTrafficListener(1, message -> adminService.onMessage(message));
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == HState.CONNECTED)
@ -89,31 +93,18 @@ public class ExtraController extends SubForm implements SocksConfiguration {
if (oldValue == HState.NOT_CONNECTED || newValue == HState.NOT_CONNECTED)
updateAdvancedUI();
});
cbx_advanced.selectedProperty().addListener(observable -> updateAdvancedUI());
enableAdvancedBox.selectedProperty().addListener(observable -> 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
public boolean useSocks() {
return cbx_useSocks.isSelected();
return advancedUseSocksBox.isSelected();
}
@Override
public int getSocksPort() {
String socksString = txt_socksIp.getText();
String socksString = advancedSocketProxyIpField.getText();
if (socksString.contains(":")) {
return Integer.parseInt(socksString.split(":")[1]);
}
@ -122,7 +113,7 @@ public class ExtraController extends SubForm implements SocksConfiguration {
@Override
public String getSocksHost() {
return txt_socksIp.getText().split(":")[0];
return advancedSocketProxyIpField.getText().split(":")[0];
}
@Override
@ -130,17 +121,13 @@ public class ExtraController extends SubForm implements SocksConfiguration {
// return cbx_socksUseIfNeeded.isSelected();
return false;
}
public boolean useGPython() {
return cbx_gpython.isSelected();
}
public void gpythonCbxClick(ActionEvent actionEvent) {
if (cbx_gpython.isSelected()) {
@FXML
public void onClickGPythonButton() {
if (enableGPythonBox.isSelected()) {
new Thread(() -> {
Platform.runLater(() -> {
cbx_gpython.setSelected(false);
cbx_gpython.setDisable(true);
enableGPythonBox.setSelected(false);
enableGPythonBox.setDisable(true);
});
if (!GPythonVersionUtils.validInstallation()) {
Platform.runLater(() -> {
@ -166,13 +153,13 @@ public class ExtraController extends SubForm implements SocksConfiguration {
e.printStackTrace();
}
cbx_gpython.setDisable(false);
enableGPythonBox.setDisable(false);
});
}
else {
Platform.runLater(() -> {
cbx_gpython.setSelected(true);
cbx_gpython.setDisable(false);
enableGPythonBox.setSelected(true);
enableGPythonBox.setDisable(false);
parentController.extensionsController.updateGPythonStatus();
});
}
@ -183,8 +170,9 @@ public class ExtraController extends SubForm implements SocksConfiguration {
}
public void developCbxClick(ActionEvent actionEvent) {
if (cbx_develop.isSelected()) {
@FXML
public void onClickDeveloperModeBox() {
if (enableDeveloperModeBox.isSelected()) {
Platform.runLater(() -> {
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"));
@ -197,7 +185,7 @@ public class ExtraController extends SubForm implements SocksConfiguration {
try {
Optional<ButtonType> result = TitleBarController.create(alert).showAlertAndWait();
if (!result.isPresent() || result.get() == ButtonType.NO) {
cbx_develop.setSelected(false);
enableDeveloperModeBox.setSelected(false);
}
else {
setDevelopMode(true);
@ -212,29 +200,47 @@ public class ExtraController extends SubForm implements SocksConfiguration {
}
}
private void setDevelopMode(boolean enabled) {
cbx_develop.setSelected(enabled);
@FXML
public void onClickClientSideStaffPermissionsBox() {
adminService.setEnabled(enableClientSideStaffPermissionsBox.isSelected());
}
public void adminCbxClick(ActionEvent actionEvent) {
adminService.setEnabled(cbx_admin.isSelected());
public boolean useGPython() {
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() {
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"));
lbl_proxyIp.textProperty().bind(new TranslatableString("%s:", "tab.extra.options.advanced.proxy.ip"));
notepadLabel.textProperty().bind(new TranslatableString("%s:", "tab.extra.notepad"));
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"));
cbx_admin.textProperty().bind(new TranslatableString("%s", "tab.extra.options.staffpermissions"));
cbx_gpython.textProperty().bind(new TranslatableString("%s", "tab.extra.options.pythonscripting"));
cbx_advanced.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced"));
enableDeveloperModeBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.developmode"));
enableClientSideStaffPermissionsBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.staffpermissions"));
enableGPythonBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.pythonscripting"));
enableAdvancedBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced"));
cbx_useSocks.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.socks"));
cbx_disableDecryption.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.disabledecryption"));
cbx_debug.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.debugstdout"));
advancedUseSocksBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.socks"));
advancedDisableDecryptionBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.disabledecryption"));
advancedEnableDebugBox.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced.debugstdout"));
}
}

View File

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

View File

@ -10,150 +10,151 @@ import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.net.URL;
import java.util.*;
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 int historylimit = 69;
private static final int MAX_HISTORY_ENTRIES = 69;
public TextArea inputPacket;
public Text lbl_corruption;
public Text lbl_pcktInfo;
public Button btn_sendToServer;
public Button btn_sendToClient;
public ListView<InjectedPackets> history;
public Label lblHistory;
public Hyperlink lnk_clearHistory;
public TextArea packetTextArea;
public Text packetCorruptedText;
public Text packetInfoText;
public Button sendToServerButton;
public Button sendToClientButton;
public ListView<InjectedPackets> historyView;
public Label historyLabel;
public Hyperlink clearHistoryLink;
private TranslatableString corruption, pcktInfo;
private TranslatableString packetCorruptedString;
private TranslatableString packetInfoString;
@Override
protected void onParentSet() {
final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI);
GEarthProperties.enableDeveloperModeProperty.addListener(updateUI);
getHConnection().stateProperty().addListener(updateUI);
inputPacket.textProperty().addListener(updateUI);
packetTextArea.textProperty().addListener(updateUI);
}
public void initialize() {
history.setOnMouseClicked(event -> {
@Override
public void initialize(URL location, ResourceBundle resources) {
historyView.setOnMouseClicked(event -> {
if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
InjectedPackets injectedPackets = history.getSelectionModel().getSelectedItem();
final InjectedPackets injectedPackets = historyView.getSelectionModel().getSelectedItem();
if (injectedPackets != null) {
Platform.runLater(() -> {
inputPacket.setText(injectedPackets.getPacketsAsString());
packetTextArea.setText(injectedPackets.getPacketsAsString());
updateUI();
});
}
}
});
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);
}
findInjectedPackets().ifPresent(this::updateHistoryView);
initLanguageBinding();
}
private static boolean isPacketIncomplete(String line) {
boolean unmatchedBrace = false;
boolean ignoreBrace = false;
for (int i = 0; i < line.length(); i++) {
if (unmatchedBrace && line.charAt(i) == '"' && line.charAt(i - 1) != '\\') {
ignoreBrace = !ignoreBrace;
@FXML
public void onClickSendToServer() {
final HPacket[] packets = parsePackets(packetTextArea.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, packetTextArea.getText(), HMessage.Direction.TOSERVER);
}
if (!ignoreBrace) {
if (line.charAt(i) == '{'){
unmatchedBrace = true;
}
else if (line.charAt(i) == '}') {
unmatchedBrace = false;
}
@FXML
public void onClickSendToClient() {
final HPacket[] packets = parsePackets(packetTextArea.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, 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) {
LinkedList<HPacket> packets = new LinkedList<>();
String[] lines = fullText.split("\n");
private void addToHistory(HPacket[] packets, String packetsAsString, HMessage.Direction direction) {
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
while (isPacketIncomplete(line) && i < lines.length - 1)
line += '\n' + lines[++i];
final InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction);
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() {
boolean dirty = false;
corruption.setFormat("%s: %s");
corruption.setKey(1, "tab.injection.corrupted.false");
lbl_corruption.getStyleClass().clear();
lbl_corruption.getStyleClass().add("not-corrupted-label");
packetCorruptedString.setFormat("%s: %s");
packetCorruptedString.setKey(1, "tab.injection.corrupted.false");
packetCorruptedText.getStyleClass().setAll("not-corrupted-label");
HPacket[] packets = parsePackets(inputPacket.getText());
final HPacket[] packets = parsePackets(packetTextArea.getText());
if (packets.length == 0) {
dirty = true;
lbl_corruption.setFill(Paint.valueOf("#ee0404b2"));
lbl_corruption.getStyleClass().clear();
lbl_corruption.getStyleClass().add("corrupted-label");
packetCorruptedText.setFill(Paint.valueOf("#ee0404b2"));
packetCorruptedText.getStyleClass().setAll("corrupted-label");
}
for (int i = 0; i < packets.length; i++) {
if (packets[i].isCorrupted()) {
if (!dirty) {
corruption.setFormat("%s: %s -> " + i);
corruption.setKey(1, "tab.injection.corrupted.true");
lbl_corruption.getStyleClass().clear();
lbl_corruption.getStyleClass().add("corrupted-label");
packetCorruptedString.setFormat("%s: %s -> " + i);
packetCorruptedString.setKey(1, "tab.injection.corrupted.true");
packetCorruptedText.getStyleClass().setAll("corrupted-label");
dirty = true;
} else
corruption.setFormat(corruption.getFormat() + ", " + i);
packetCorruptedString.setFormat(packetCorruptedString.getFormat() + ", " + i);
}
}
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) {
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));
boolean canSendToServer = Arrays.stream(packets).allMatch(packet ->
final boolean canSendToServer = Arrays.stream(packets).allMatch(packet ->
connection.canSendPacket(HMessage.Direction.TOSERVER, packet));
btn_sendToClient.setDisable(!canSendToClient);
btn_sendToServer.setDisable(!canSendToServer);
sendToClientButton.setDisable(!canSendToClient);
sendToServerButton.setDisable(!canSendToServer);
// mark packet sending unsafe if there is any packet that is unsafe for both TOSERVER and TOCLIENT
boolean isUnsafe = Arrays.stream(packets).anyMatch(packet ->
@ -163,122 +164,87 @@ public class InjectionController extends SubForm {
if (packets.length == 1) {
HPacket packet = packets[0];
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.id",
"tab.injection.description.length",
"tab.injection.description.unsafe");
}
else {
pcktInfo.setFormatAndKeys("%s (%s: " + packet.headerId() + ", %s: " + packet.length() + ")",
} else {
packetInfoString.setFormatAndKeys("%s (%s: " + packet.headerId() + ", %s: " + packet.length() + ")",
"tab.injection.description.header",
"tab.injection.description.id",
"tab.injection.description.length");
}
}
else {
} else {
if (isUnsafe) {
pcktInfo.setFormatAndKeys("%s", "tab.injection.description.unsafe");
}
else {
pcktInfo.setFormatAndKeys("");
packetInfoString.setFormatAndKeys("%s", "tab.injection.description.unsafe");
} else {
packetInfoString.setFormatAndKeys("");
}
}
} else {
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.id",
"tab.injection.description.length");
} else {
packetInfoString.setFormatAndKeys("");
}
else {
pcktInfo.setFormatAndKeys("");
sendToClientButton.setDisable(true);
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() {
lblHistory.textProperty().bind(new TranslatableString("%s", "tab.injection.history"));
lblHistory.setTooltip(new Tooltip());
lblHistory.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.injection.history.tooltip"));
historyLabel.textProperty().bind(new TranslatableString("%s", "tab.injection.history"));
historyLabel.setTooltip(new Tooltip());
historyLabel.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.injection.history.tooltip"));
corruption = new TranslatableString("%s: %s", "tab.injection.corrupted", "tab.injection.corrupted.true");
lbl_corruption.textProperty().bind(corruption);
packetCorruptedString = new TranslatableString("%s: %s", "tab.injection.corrupted", "tab.injection.corrupted.true");
packetCorruptedText.textProperty().bind(packetCorruptedString);
pcktInfo = new TranslatableString("%s (%s:NULL, %s:0)", "tab.injection.description.header", "tab.injection.description.id", "tab.injection.description.length");
lbl_pcktInfo.textProperty().bind(pcktInfo);
packetInfoString = new TranslatableString("%s (%s:NULL, %s:0)", "tab.injection.description.header", "tab.injection.description.id", "tab.injection.description.length");
packetInfoText.textProperty().bind(packetInfoString);
btn_sendToServer.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toserver"));
btn_sendToClient.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toclient"));
sendToServerButton.textProperty().bind(new TranslatableString("%s", "tab.injection.send.toserver"));
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) {
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}");
System.out.println(new HPacket("{l}{h:2550}{s:\"ClientPerf\"\"ormance\\\"}\"}{s:\"23\"}{s:\"fps\"}{s:\"Avatars: 1, Objects: 0\"}{i:76970180}").toExpression());
private static Optional<List<InjectedPackets>> findInjectedPackets() {
return Optional.ofNullable(Cacher.getList(HISTORY_CACHE_KEY))
.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,24 +20,22 @@ import java.util.Calendar;
public class LoggerController extends SubForm {
public TextField txtPacketLimit;
public CheckBox cbx_blockIn;
public CheckBox cbx_blockOut;
public CheckBox cbx_showAdditional;
public CheckBox cbx_splitPackets;
public CheckBox cbx_useLog;
public TextFlow txt_logField;
public Button btnUpdate;
public CheckBox cbx_showstruct;
public TextField packetLimitField;
public CheckBox hideIncomingPacketsBox;
public CheckBox hideOutgoingPacketsBox;
public CheckBox showPacketStructureBox;
public CheckBox showAdditionalPacketInfoBox;
public CheckBox splitPacketsBox;
public CheckBox enableLoggingBox;
public TextFlow loggingField;
public Button updateButton;
private int packetLimit = 8000;
private PacketLoggerFactory packetLoggerFactory;
private PacketLogger packetLogger;
public void onParentSet() {
packetLoggerFactory = new PacketLoggerFactory(parentController.extensionsController.getExtensionHandler());
packetLogger = packetLoggerFactory.get();
packetLogger = new PacketLoggerFactory(parentController.extensionsController.getExtensionHandler()).get();
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(() -> {
if (newState == HState.PREPARING) {
@ -53,25 +51,30 @@ public class LoggerController extends SubForm {
}
}));
getHConnection().addTrafficListener(2, message -> { Platform.runLater(() -> {
if (message.getDestination() == HMessage.Direction.TOCLIENT && cbx_blockIn.isSelected() ||
message.getDestination() == HMessage.Direction.TOSERVER && cbx_blockOut.isSelected()) return;
getHConnection().addTrafficListener(2, message -> {
Platform.runLater(() -> {
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();
}
int types = 0;
if (message.getDestination() == HMessage.Direction.TOCLIENT) types |= PacketLogger.MESSAGE_TYPE.INCOMING.getValue();
else if (message.getDestination() == HMessage.Direction.TOSERVER) types |= PacketLogger.MESSAGE_TYPE.OUTGOING.getValue();
if (message.getDestination() == HMessage.Direction.TOCLIENT)
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.isBlocked()) types |= PacketLogger.MESSAGE_TYPE.BLOCKED.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);
if (cbx_showstruct.isSelected() && message.getPacket().length() < packetLimit) {
if (showPacketStructureBox.isSelected() && message.getPacket().length() < packetLimit) {
packetLogger.appendStructure(message.getPacket(), message.getDestination());
}
});
@ -79,49 +82,49 @@ public class LoggerController extends SubForm {
}
public void updatePacketLimit(ActionEvent actionEvent) {
packetLimit = Integer.parseInt(txtPacketLimit.getText());
packetLimit = Integer.parseInt(packetLimitField.getText());
}
@SuppressWarnings("Duplicates")
public void initialize() {
txtPacketLimit.textProperty().addListener(observable -> {
packetLimitField.textProperty().addListener(observable -> {
boolean isInt = true;
try {
Integer.parseInt(txtPacketLimit.getText());
Integer.parseInt(packetLimitField.getText());
} catch (NumberFormatException e) {
isInt = false;
}
btnUpdate.setDisable(!isInt);
updateButton.setDisable(!isInt);
});
txtPacketLimit.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btnUpdate.isDisable()) {
packetLimitField.setOnKeyPressed(event -> {
if (event.getCode().equals(KeyCode.ENTER) && !updateButton.isDisable()) {
updatePacketLimit(null);
}
});
}
public void miniLogText(Color color, String text) {
if (cbx_useLog.isSelected()) {
String color2 = "#" + color.toString().substring(2, 8);
if (enableLoggingBox.isSelected()) {
final String color2 = "#" + color.toString().substring(2, 8);
Calendar rightNow = Calendar.getInstance();
String hour = addToNumber(""+rightNow.get(Calendar.HOUR_OF_DAY));
String minutes = addToNumber(""+rightNow.get(Calendar.MINUTE));
String seconds = addToNumber(""+rightNow.get(Calendar.SECOND));
final Calendar rightNow = Calendar.getInstance();
final String hour = addToNumber("" + rightNow.get(Calendar.HOUR_OF_DAY));
final String minutes = addToNumber("" + rightNow.get(Calendar.MINUTE));
final String seconds = addToNumber("" + rightNow.get(Calendar.SECOND));
String timestamp = "[" + hour + ":" + minutes + ":" + seconds + "] ";
timestamp = timestamp.replace(" ", "\u00A0"); // disable automatic linebreaks
Text time = new Text(timestamp);
final Text time = new Text(timestamp);
time.setStyle("-fx-opacity: " + 0.5 + ";");
text = text.replace(" ", "\u00A0");
Text otherText = new Text(text + "\n");
final Text otherText = new Text(text + "\n");
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;
return text;
}
}

View File

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

View File

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

View File

@ -1,73 +1,87 @@
package gearth.ui.subforms.scheduler;
import com.tulskiy.keymaster.common.Provider;
import gearth.extensions.parsers.HDirection;
import gearth.protocol.HConnection;
import gearth.protocol.StateChangeListener;
import gearth.protocol.connection.HState;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.services.scheduler.Interval;
import gearth.services.scheduler.Scheduler;
import gearth.ui.GEarthProperties;
import gearth.ui.SubForm;
import gearth.ui.translations.LanguageBundle;
import gearth.ui.translations.TranslatableString;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.ui.SubForm;
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.List;
import java.util.function.Consumer;
import java.util.ResourceBundle;
/**
* 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 HPacket defaultPacket = new HPacket("Chat", HMessage.Direction.TOCLIENT, -1, "Frank loves G-Earth", 0, 33, 0, 0);
public VBox schedulecontainer;
public GridPane header;
public VBox root;
public GridPane headerGrid;
public ScrollPane scrollpane;
public Button btn_addoredit;
public Button addOrEditButton;
public TextField txt_delay;
public ToggleGroup scheduler_dest;
public TextField txt_packet;
public RadioButton rb_incoming;
public RadioButton rb_outgoing;
public TextField packetDelayField;
public TextField packetExpressionField;
public Button btn_clear;
public Button btn_save;
public Button btn_load;
public ToggleGroup packetTypeOptions;
public RadioButton packetIncomingOption;
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 Scheduler<InteractableScheduleItem> scheduler = null;
private TranslatableString addoredit;
public Label lbl_tableIndex, lbl_tablePacket, lbl_tableInterval, lbl_tableDest, lbl_tableEdit, lbl_setupPacket, lbl_setupInterval;
@Override
public void initialize(URL location, ResourceBundle resources) {
scrollpane.widthProperty().addListener(observable -> headerGrid.setPrefWidth(scrollpane.getWidth()));
packetTypeOptions.selectToggle(packetTypeOptions.getToggles().get(0));
public void initialize() {
scrollpane.widthProperty().addListener(observable -> header.setPrefWidth(scrollpane.getWidth()));
scheduler_dest.selectToggle(scheduler_dest.getToggles().get(0));
packetExpressionField.textProperty().addListener(event -> Platform.runLater(this::updateUI));
packetDelayField.textProperty().addListener(event -> Platform.runLater(this::updateUI));
txt_packet.textProperty().addListener(event -> Platform.runLater(this::updateUI));
txt_delay.textProperty().addListener(event -> Platform.runLater(this::updateUI));
clearButton.setOnAction(a -> clear());
//register hotkeys
//disable some output things
@ -97,65 +111,93 @@ public class SchedulerController extends SubForm {
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) {
if (cbx_hotkeys.isSelected() && index < scheduler.size()) {
if (enableHotkeysBox.isSelected() && index < scheduler.size()) {
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() {
HConnection connection = getHConnection();
if (connection == null) return;
HMessage.Direction direction = rb_incoming.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER;
HPacket packet = new HPacket(txt_packet.getText());
boolean isPacketOk = connection.canSendPacket(direction, packet);
final HConnection connection = getHConnection();
btn_addoredit.setDisable(!Interval.isValid(txt_delay.getText()) || !isPacketOk);
}
if (connection == null)
return;
public void scheduleBtnClicked(ActionEvent actionEvent) {
if (isBeingEdited == null) {
HPacket packet = new HPacket(txt_packet.getText());
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);
}
final HMessage.Direction direction = packetIncomingOption.isSelected() ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER;
final HPacket packet = new HPacket(packetExpressionField.getText());
final boolean isPacketOk = connection.canSendPacket(direction, packet);
addOrEditButton.setDisable(!Interval.isValid(packetDelayField.getText()) || !isPacketOk);
}
private void addItem(InteractableScheduleItem newItem) {
new ScheduleItemContainer(newItem, schedulecontainer, scrollpane);
new ScheduleItemContainer(newItem, root, scrollpane);
scheduler.add(newItem);
newItem.onDelete(() -> {
if (isBeingEdited == newItem) {
setInputDefault(false);
@ -172,13 +214,13 @@ public class SchedulerController extends SubForm {
}
if (isBeingEdited != newItem) {
txt_packet.setText(newItem.getPacketAsStringProperty().get());
txt_delay.setText(newItem.getDelayProperty().get().toString());
rb_incoming.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOCLIENT);
rb_outgoing.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOSERVER);
packetExpressionField.setText(newItem.getPacketAsStringProperty().get());
packetDelayField.setText(newItem.getDelayProperty().get().toString());
packetIncomingOption.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOCLIENT);
packetOutgoingOption.setSelected(newItem.getDestinationProperty().get() == HMessage.Direction.TOSERVER);
isBeingEdited = newItem;
addoredit.setKey(0, "tab.scheduler.button.edit");
addOrEditString.setKey(0, "tab.scheduler.button.edit");
updateUI();
newItem.onIsBeingUpdatedTrigger();
}
@ -191,127 +233,53 @@ public class SchedulerController extends SubForm {
}
private void setInputDefault(boolean showDummyPacket) {
txt_delay.setText(defaultInterval.toString());
txt_packet.setText(showDummyPacket ? defaultPacket.toExpression() : "");
rb_incoming.setSelected(true);
rb_outgoing.setSelected(false);
packetDelayField.setText(defaultInterval.toString());
packetExpressionField.setText(showDummyPacket ? defaultPacket.toExpression() : "");
packetIncomingOption.setSelected(true);
packetOutgoingOption.setSelected(false);
addoredit.setKey(0, "tab.scheduler.button.add");
addOrEditString.setKey(0, "tab.scheduler.button.add");
updateUI();
}
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();
}
}
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() {
addoredit = new TranslatableString("%s", "tab.scheduler.button.add");
btn_addoredit.textProperty().bind(addoredit);
addOrEditString = new TranslatableString("%s", "tab.scheduler.button.add");
addOrEditButton.textProperty().bind(addOrEditString);
btn_clear.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear"));
btn_clear.setTooltip(new Tooltip());
btn_clear.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear.tooltip"));
clearButton.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear"));
clearButton.setTooltip(new Tooltip());
clearButton.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.clear.tooltip"));
btn_save.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save"));
btn_save.setTooltip(new Tooltip());
btn_save.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save.tooltip"));
saveButton.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save"));
saveButton.setTooltip(new Tooltip());
saveButton.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.save.tooltip"));
btn_load.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load"));
btn_load.setTooltip(new Tooltip());
btn_load.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load.tooltip"));
loadButton.textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load"));
loadButton.setTooltip(new Tooltip());
loadButton.getTooltip().textProperty().bind(new TranslatableString("%s", "tab.scheduler.button.load.tooltip"));
lbl_tableIndex.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.index"));
lbl_tablePacket.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.packet"));
lbl_tableInterval.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.interval"));
lbl_tableDest.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.destination"));
lbl_tableEdit.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.edit"));
tableIndexLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.index"));
tablePacketLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.packet"));
tableIntervalLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.interval"));
tableDestinationLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.destination"));
tableEditLabel.textProperty().bind(new TranslatableString("%s", "tab.scheduler.table.edit"));
lbl_setupPacket.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.packet"));
lbl_setupInterval.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.interval"));
packetExpressionLabel.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.packet"));
packetIntervalLabel.textProperty().bind(new TranslatableString("%s:", "tab.scheduler.setup.interval"));
rb_incoming.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.in"));
rb_outgoing.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.out"));
packetIncomingOption.textProperty().bind(new TranslatableString("%s", "tab.scheduler.direction.in"));
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;
import gearth.services.packet_info.PacketInfoManager;
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.misc.BindingsUtil;
import gearth.protocol.HPacket;
import gearth.services.packet_info.PacketInfoManager;
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.util.ResourceBundle;
public class ToolsController extends SubForm implements Initializable {
public class ToolsController extends SubForm {
public TextField txt_intDecoded;
public TextField txt_intEncoded;
public TextField txt_ushortDecoded;
public TextField txt_ushortEncoded;
public Button btnEncodeInt;
public Button btnDecodeInt;
public Button btnEncodeUShort;
public Button btnDecodeUshort;
public TextField decodedIntegerField;
public TextField encodedIntegerField;
public TextField decodedUShortField;
public TextField encodedUShortField;
public Button encodeIntegerButton;
public Button decodeIntegerButton;
public Button encodeUShortButton;
public Button decodeUShortButton;
public Button btn_toExpr;
public TextArea txt_packetArea;
public Button btn_toPacket;
public TextArea txt_exprArea;
public TextArea packetArea;
public TextArea expressionArea;
public Button convertPacketToExpressionButton;
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
public void initialize() {
txt_packetArea.textProperty().addListener(observable -> {
btn_toExpr.setDisable(new HPacket(txt_packetArea.getText()).isCorrupted());
});
@Override
public void initialize(URL location, ResourceBundle resources) {
txt_packetArea.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btn_toExpr.isDisable()) {
btn_toExpr_clicked(null);
}
});
convertPacketToExpressionButton.disableProperty().bind(packetIsCorruptBinding(packetArea));
convertExpressionToPacketButton.disableProperty().bind(packetIsCorruptBinding(expressionArea));
txt_exprArea.textProperty().addListener(observable -> {
btn_toPacket.setDisable(new HPacket(txt_exprArea.getText()).isCorrupted());
});
encodeIntegerButton.disableProperty().bind(BindingsUtil.isInteger(decodedIntegerField.textProperty()).not());
decodeIntegerButton.disableProperty().bind(packetLengthEqualsBinding(encodedIntegerField, Integer.BYTES).not());
txt_exprArea.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER) && !btn_toPacket.isDisable()) {
btn_toPacket_clicked(null);
}
});
encodeUShortButton.disableProperty().bind(BindingsUtil.isUShort(decodedUShortField.textProperty()).not());
decodeUShortButton.disableProperty().bind(packetLengthEqualsBinding(encodedUShortField, Short.BYTES).not());
txt_intDecoded.textProperty().addListener(observable -> {
boolean isInt = true;
try {
Integer.parseInt(txt_intDecoded.getText());
} 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);
}
});
fireButtonOnPressEnter(packetArea, convertPacketToExpressionButton);
fireButtonOnPressEnter(expressionArea, convertExpressionToPacketButton);
fireButtonOnPressEnter(decodedIntegerField, encodeIntegerButton);
fireButtonOnPressEnter(decodedUShortField, encodeUShortButton);
fireButtonOnPressEnter(encodedIntegerField, decodeIntegerButton);
fireButtonOnPressEnter(encodedUShortField, decodeUShortButton);
initLanguageBinding();
}
public void btnEncodeInt_clicked(ActionEvent actionEvent) {
ByteBuffer b = ByteBuffer.allocate(4);
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 packetIsCorruptBinding(TextInputControl input) {
return Bindings.createBooleanBinding(() -> new HPacket(input.getText()).isCorrupted(), input.textProperty());
}
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) {
PacketInfoManager packetInfoManager = getHConnection().getPacketInfoManager();
HPacket packet = new HPacket(p);
if (!packet.isPacketComplete() && packetInfoManager != null) {
final PacketInfoManager packetInfoManager = getHConnection().getPacketInfoManager();
final HPacket packet = new HPacket(p);
if (!packet.isPacketComplete() && packetInfoManager != null)
packet.completePacket(packetInfoManager);
}
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() {
lbl_integer.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.integer"));
lbl_uShort.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.ushort"));
integerLabel.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.integer"));
uShortLabel.textProperty().bind(new TranslatableString("%s:", "tab.tools.type.ushort"));
TranslatableString encode = new TranslatableString("%s", "tab.tools.button.encode");
TranslatableString decode = new TranslatableString("%s", "tab.tools.button.decode");
btnEncodeInt.textProperty().bind(encode);
btnEncodeUShort.textProperty().bind(encode);
btnDecodeInt.textProperty().bind(decode);
btnDecodeUshort.textProperty().bind(decode);
final TranslatableString encode = new TranslatableString("%s", "tab.tools.button.encode");
final TranslatableString decode = new TranslatableString("%s", "tab.tools.button.decode");
encodeIntegerButton.textProperty().bind(encode);
encodeUShortButton.textProperty().bind(encode);
decodeIntegerButton.textProperty().bind(decode);
decodeUShortButton.textProperty().bind(decode);
lbl_encodingDecoding.textProperty().bind(new TranslatableString("%s/%s", "tab.tools.encoding", "tab.tools.decoding"));
lbl_packetToExpression.textProperty().bind(new TranslatableString("%s <-> %s", "tab.tools.packet", "tab.tools.expression"));
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"));
}
}

View File

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

View File

@ -45,8 +45,8 @@
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<Label fx:id="lblInpPort" text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpPort" disable="true" editable="true" prefWidth="183.0" GridPane.columnIndex="1">
<Label fx:id="portOptionsLabel" text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="portOptionsBox" disable="true" editable="true" prefWidth="183.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
@ -60,8 +60,8 @@
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<Label fx:id="lblInpHost" text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpHost" disable="true" editable="true" GridPane.columnIndex="1">
<Label fx:id="hostOptionsLabel" text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="hostOptionsBox" disable="true" editable="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
@ -78,12 +78,12 @@
<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>
<Insets left="-5.0" />
</GridPane.margin>
</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>
<Insets left="15.0" right="15.0" />
</GridPane.margin>
@ -111,8 +111,8 @@
<RowConstraints maxHeight="86.0" minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label fx:id="lblHotelVersion" text="Hotel version:" textFill="#000000cc" />
<TextField fx:id="txtfield_hotelversion" editable="false" prefHeight="17.0" prefWidth="285.0" GridPane.rowIndex="1">
<Label fx:id="connectedHotelVersionLabel" text="Hotel version:" textFill="#000000cc" />
<TextField fx:id="connectedHotelVersionField" editable="false" prefHeight="17.0" prefWidth="285.0" GridPane.rowIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
@ -125,7 +125,7 @@
<Insets left="12.0" right="10.0" top="5.0" />
</GridPane.margin>
</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 hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="76.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>
<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>
<Insets left="8.0" />
</padding>
@ -145,20 +145,20 @@
<Insets right="-20.0" />
</GridPane.margin>
</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 fx:id="tgl_clientMode" />
<ToggleGroup fx:id="clientTypeOptions" />
</toggleGroup>
<GridPane.margin>
<Insets />
</GridPane.margin>
</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>
<Insets />
</GridPane.margin>
</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>
<Insets />
</GridPane.margin>
@ -196,7 +196,7 @@
<GridPane.margin>
<Insets bottom="14.0" left="20.0" right="20.0" />
</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>
<Insets bottom="5.0" left="2.0" />
</GridPane.margin>
@ -204,7 +204,7 @@
<Font size="12.0" />
</font>
</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>
<Insets />
</GridPane.margin>
@ -225,17 +225,17 @@
<padding>
<Insets bottom="7.0" top="7.0" />
</padding>
<Label fx:id="lblHost" text="Host:" textFill="#000000cc">
<Label fx:id="connectedHostLabel" text="Host:" textFill="#000000cc">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</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>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<TextField fx:id="outHost" editable="false" GridPane.columnIndex="1">
<TextField fx:id="connectedHostField" editable="false" GridPane.columnIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
@ -243,7 +243,7 @@
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</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>
<Insets left="5.0" right="10.0" />
</GridPane.margin>

View File

@ -12,12 +12,12 @@
<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>
<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>
<Insets bottom="8.0" left="17.0" right="17.0" top="17.0" />
</GridPane.margin>
<VBox fx:id="extensioncontainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<GridPane fx:id="header_ext" gridLinesVisible="true" styleClass="table-header">
<VBox fx:id="contentBox" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<GridPane fx:id="headerGridPane" gridLinesVisible="true" styleClass="table-header">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="22.0" prefWidth="132.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="34.0" prefWidth="204.0" />
@ -31,11 +31,11 @@
<VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</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="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="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="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="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="tableTitleLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Title" />
<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="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="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="tableEditLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" />
</GridPane>
</VBox>
</ScrollPane>
@ -61,19 +61,19 @@
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</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" />
<TextField fx:id="ext_port" editable="false" prefHeight="26.0" prefWidth="157.0" GridPane.columnIndex="1">
<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="portField" editable="false" prefHeight="26.0" prefWidth="157.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets left="-7.0" />
</GridPane.margin>
</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>
<Insets left="3.0" />
</GridPane.margin>
</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="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="installButton" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickInstallButton" text="Install" GridPane.columnIndex="5" />
<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>

View File

@ -16,10 +16,10 @@
<children>
<AnchorPane prefHeight="262.0" prefWidth="318.0">
<children>
<CheckBox fx:id="cbx_alwaysOnTop" 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" />
<Label fx:id="lbl_notepad" 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" />
<CheckBox fx:id="alwaysOnTopBox" layoutX="14.0" layoutY="232.0" mnemonicParsing="false" text="Always on top" />
<Hyperlink fx:id="troubleshootingLink" alignment="CENTER_RIGHT" layoutX="170.0" layoutY="232.0" prefWidth="150.0" text="Troubleshooting" />
<Label fx:id="notepadLabel" layoutX="14.0" layoutY="8.0" text="Notepad:" textFill="#000000bd" />
<TextArea fx:id="notepadTextArea" layoutX="11.0" layoutY="31.0" prefHeight="197.0" prefWidth="312.0" />
</children>
</AnchorPane>
<GridPane GridPane.columnIndex="1">
@ -35,7 +35,7 @@
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="232.0" vgrow="SOMETIMES" />
</rowConstraints>
<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 hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
@ -52,10 +52,10 @@
<Insets left="7.0" top="3.0" />
</padding>
<children>
<CheckBox fx:id="cbx_useSocks" mnemonicParsing="false" text="Use SOCKS proxy" />
<CheckBox fx:id="cbx_disableDecryption" mnemonicParsing="false" text="Disable decryption" GridPane.rowIndex="2" />
<CheckBox fx:id="cbx_debug" 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">
<CheckBox fx:id="advancedUseSocksBox" mnemonicParsing="false" text="Use SOCKS proxy" />
<CheckBox fx:id="advancedDisableDecryptionBox" mnemonicParsing="false" text="Disable decryption" GridPane.rowIndex="2" />
<CheckBox fx:id="advancedEnableDebugBox" mnemonicParsing="false" text="Debug to stdout" GridPane.rowIndex="3" />
<GridPane fx:id="advancedSocksInfoGrid" disable="true" prefHeight="54.0" prefWidth="81.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
@ -78,8 +78,8 @@
<RowConstraints maxHeight="2.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label fx:id="lbl_proxyIp" text="Proxy IP:" />
<TextField fx:id="txt_socksIp" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="ip:port" GridPane.columnIndex="1">
<Label fx:id="advancedSocksProxyIpLabel" text="Proxy IP:" />
<TextField fx:id="advancedSocketProxyIpField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="ip:port" GridPane.columnIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
@ -96,7 +96,7 @@
</GridPane>
</children>
</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>
<Insets left="10.0" top="2.0" />
</GridPane.margin>
@ -104,17 +104,17 @@
<Insets top="2.0" />
</padding>
</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>
<Insets left="10.0" top="2.0" />
</GridPane.margin>
</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>
<Insets left="10.0" top="2.0" />
</GridPane.margin>
</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>
<Insets left="10.0" />
</GridPane.margin>

View File

@ -14,18 +14,18 @@
</rowConstraints>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<ImageView fx:id="img_logo" 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">
<ImageView fx:id="logoImageView" fitHeight="228.0" fitWidth="217.0" layoutX="23.0" layoutY="23.0" pickOnBounds="true" preserveRatio="true" />
<Label fx:id="themeTitleLabel" layoutX="260.0" layoutY="23.0" text="\$theme $version" textFill="#000000b2">
<font>
<Font size="18.0" />
</font>
</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 size="14.0" />
</font>
</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 name="System Bold" size="14.0" />
</font>
@ -35,7 +35,7 @@
<Font size="14.0" />
</font>
</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 name="System Bold" size="14.0" />
</font>
@ -75,18 +75,18 @@
<Font size="14.0" />
</font>
</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 name="System Bold" size="14.0" />
</font>
</Label>
<Hyperlink fx:id="link_darkbox" 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="link_g_tanji" 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="link_g_store" 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" />
<Hyperlink fx:id="link_t_gearth" layoutX="487.0" layoutY="192.0" text="Twitter - G-Earth" />
<Hyperlink fx:id="darkBoxLink" layoutX="487.0" layoutY="112.0" text="Darkbox" />
<Hyperlink fx:id="githubGEarthLink" layoutX="487.0" layoutY="132.0" text="Github - G-Earth" />
<Hyperlink fx:id="githubTanjiLink" layoutX="487.0" layoutY="152.0" text="Github - Tanji" />
<Hyperlink fx:id="discordGEarthLink" layoutX="487.0" layoutY="172.0" text="Discord - G-Earth" />
<Hyperlink fx:id="githubExtensionStoreLink" layoutX="487.0" layoutY="212.0" text="G-ExtensionStore" />
<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="twitterGEarthLink" layoutX="487.0" layoutY="192.0" text="Twitter - G-Earth" />
<Label layoutX="363.0" layoutY="204.0" text="Dorving" textFill="#000000b2">
<font>
<Font size="14.0" />

View File

@ -37,18 +37,18 @@
<GridPane.margin>
<Insets left="13.0" right="13.0" top="4.0" />
</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 name="System Italic" size="11.0" />
</font>
</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 name="System Italic" size="11.0" />
</font>
</Text>
</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>
<Insets bottom="5.0" left="10.0" right="10.0" />
</GridPane.margin>
@ -61,12 +61,12 @@
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</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>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</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>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
@ -82,7 +82,7 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<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>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
@ -92,11 +92,11 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<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>
<Insets right="6.0" />
</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>
<Insets />
</GridPane.margin>

View File

@ -53,13 +53,13 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
</rowConstraints>
<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>
<Insets right="8.0"/>
</GridPane.margin>
</TextField>
</GridPane>
<Button fx:id="btnUpdate" alignment="CENTER" maxHeight="1.7976931348623157E308"
<Button fx:id="updateButton" alignment="CENTER" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#updatePacketLimit" prefHeight="44.0" prefWidth="62.0" text="Update"
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS"
@ -69,18 +69,18 @@
</GridPane.margin>
</Button>
</GridPane>
<CheckBox fx:id="cbx_blockIn" mnemonicParsing="false" text="Block Incoming"/>
<CheckBox fx:id="cbx_blockOut" mnemonicParsing="false" text="Block Outgoing"/>
<CheckBox fx:id="hideIncomingPacketsBox" mnemonicParsing="false" text="Block Incoming"/>
<CheckBox fx:id="hideOutgoingPacketsBox" mnemonicParsing="false" text="Block Outgoing"/>
</VBox>
<VBox alignment="BOTTOM_LEFT" prefHeight="99.0" prefWidth="198.0" spacing="8.0" GridPane.rowIndex="1">
<GridPane.margin>
<Insets/>
</GridPane.margin>
<CheckBox fx:id="cbx_showAdditional" mnemonicParsing="false" selected="true"
<CheckBox fx:id="showAdditionalPacketInfoBox" mnemonicParsing="false" selected="true"
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"/>
<CheckBox fx:id="cbx_splitPackets" mnemonicParsing="false" selected="true"
<CheckBox fx:id="splitPacketsBox" mnemonicParsing="false" selected="true"
text="Split packets"/>
</VBox>
</GridPane>
@ -98,7 +98,7 @@
<padding>
<Insets bottom="10.0" left="7.0" right="7.0" top="6.0"/>
</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>
<Insets left="5.0"/>
</GridPane.margin>
@ -106,7 +106,7 @@
<ScrollPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
style="-fx-border-color: #888888; -fx-border-radius: 1px; -fx-background: #FFFFFF;"
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>
<Insets/>
</GridPane.margin>

View File

@ -16,8 +16,8 @@
<GridPane.margin>
<Insets bottom="8.0" left="17.0" right="17.0" top="17.0" />
</GridPane.margin>
<VBox fx:id="schedulecontainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<GridPane fx:id="header" gridLinesVisible="true" styleClass="table-header">
<VBox fx:id="root" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<GridPane fx:id="headerGrid" gridLinesVisible="true" styleClass="table-header">
<columnConstraints>
<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" />
@ -31,11 +31,11 @@
<VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</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="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="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="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="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="tableIndexLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Index" />
<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="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="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="tableEditLabel" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" />
</GridPane>
</VBox>
</ScrollPane>
@ -62,19 +62,19 @@
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</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>
<Insets left="-7.0" />
</GridPane.margin>
</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>
<Insets left="3.0" />
</GridPane.margin>
</Label>
<Button fx:id="btn_clear" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#clearBtnClicked" 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="btn_load" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#loadBtnClicked" text="L" GridPane.columnIndex="5" />
<Button fx:id="clearButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Clear" GridPane.columnIndex="3" />
<Button fx:id="saveButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickSaveButton" text="S" GridPane.columnIndex="4" />
<Button fx:id="loadButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickLoadButton" text="L" GridPane.columnIndex="5" />
</GridPane>
<GridPane prefHeight="33.0" prefWidth="502.0" GridPane.rowIndex="1">
<columnConstraints>
@ -91,35 +91,35 @@
<GridPane.margin>
<Insets />
</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>
<Insets right="5.0" />
</GridPane.margin>
</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>
<Insets left="3.0" />
</GridPane.margin>
</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>
<Insets bottom="2.0" left="5.0" top="2.0" />
</GridPane.margin>
</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>
<Insets left="5.0" />
</GridPane.margin>
<toggleGroup>
<ToggleGroup fx:id="scheduler_dest" />
<ToggleGroup fx:id="packetTypeOptions" />
</toggleGroup>
</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>
<Insets left="5.0" />
</GridPane.margin>
</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>
<Insets left="32.0" />
</GridPane.margin>

View File

@ -46,69 +46,69 @@
<GridPane.margin>
<Insets/>
</GridPane.margin>
<Label fx:id="lbl_integer" alignment="CENTER" text="Integer:">
<Label fx:id="integerLabel" alignment="CENTER" text="Integer:">
<GridPane.margin>
<Insets left="10.0"/>
</GridPane.margin>
</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">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</TextField>
<Button fx:id="btnEncodeInt" disable="true" maxHeight="1.7976931348623157E308"
<Button fx:id="encodeIntegerButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btnEncodeInt_clicked" text="Encode" GridPane.columnIndex="2"
onAction="#onClickEncodeIntegerButton" text="Encode" GridPane.columnIndex="2"
GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</Button>
<Button fx:id="btnDecodeInt" disable="true" maxHeight="1.7976931348623157E308"
<Button fx:id="decodeIntegerButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false"
onAction="#btnDecodeInt_clicked" text="Decode" GridPane.columnIndex="3"
onAction="#onClickDecodeIntegerButton" text="Decode" GridPane.columnIndex="3"
GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</Button>
<TextField fx:id="txt_intEncoded" maxHeight="1.7976931348623157E308"
<TextField fx:id="encodedIntegerField" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" GridPane.columnIndex="4">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</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>
<Insets left="10.0"/>
</GridPane.margin>
</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"
GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</TextField>
<Button fx:id="btnEncodeUShort" disable="true" maxHeight="1.7976931348623157E308"
<Button fx:id="encodeUShortButton" disable="true" maxHeight="1.7976931348623157E308"
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.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</Button>
<Button fx:id="btnDecodeUshort" disable="true" maxHeight="1.7976931348623157E308"
<Button fx:id="decodeUShortButton" disable="true" maxHeight="1.7976931348623157E308"
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.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</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">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
@ -116,7 +116,7 @@
</TextField>
</GridPane>
<Label fx:id="lbl_encodingDecoding" text="Encoding/Decoding" textFill="#000000cc">
<Label fx:id="encodingOrDecodingLabel" text="Encoding/Decoding" textFill="#000000cc">
<GridPane.margin>
<Insets left="6.0" top="5.0"/>
</GridPane.margin>
@ -149,29 +149,29 @@
<GridPane.margin>
<Insets/>
</GridPane.margin>
<Button fx:id="btn_toExpr" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btn_toExpr_clicked"
<Button fx:id="convertPacketToExpressionButton" disable="true" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#onClickPacketToExpressionButton"
text="------&gt;" GridPane.columnIndex="1" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</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"
GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="7.0" right="5.0" top="7.0"/>
</GridPane.margin>
</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"
onAction="#btn_toPacket_clicked" text="&lt;------" GridPane.columnIndex="2"
onAction="#onClickExpressionToPacketButton" text="&lt;------" GridPane.columnIndex="2"
GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0"/>
</GridPane.margin>
</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"
GridPane.columnIndex="3" GridPane.halignment="CENTER">
<GridPane.margin>
@ -179,7 +179,7 @@
</GridPane.margin>
</TextArea>
</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>
<Insets left="6.0" top="2.0"/>
</GridPane.margin>

View File

@ -15,17 +15,17 @@
<RowConstraints maxHeight="25.0" minHeight="25.0" prefHeight="25.0" vgrow="SOMETIMES" />
</rowConstraints>
<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 url="@files/minimizeButton.png" />
</image>
</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 url="@files/closeButton.png" />
</image>
</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 hgrow="SOMETIMES" maxWidth="7.0" minWidth="7.0" prefWidth="7.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" />
@ -48,11 +48,11 @@
<Insets left="2.0" />
</padding>
</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>
</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 url="@../themes/G-Earth/themeButton.png" />
</image>