Merge pull request #11 from sirjonasxx/development

Development
This commit is contained in:
sirjonasxx 2018-11-07 16:03:52 +01:00 committed by GitHub
commit f33e74d944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
126 changed files with 3072 additions and 1475 deletions

View File

@ -13,7 +13,7 @@
<parent>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-Parent</artifactId>
<version>0.0.1-beta</version>
<version>0.2</version>
</parent>
<build>
@ -30,53 +30,6 @@
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/bin/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@ -93,7 +46,34 @@
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<finalName>${artifactId}</finalName>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/bin</outputDirectory>
<archive>
<manifest>
<mainClass>extensions.adminonconnect.AdminOnConnect</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${project.artifactId}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
</plugins>
@ -102,8 +82,8 @@
<dependencies>
<dependency>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-UI</artifactId>
<version>0.0.1-beta</version>
<artifactId>G-Earth</artifactId>
<version>0.2</version>
<!--<scope>provided</scope>-->
</dependency>
</dependencies>

View File

@ -13,7 +13,7 @@
<parent>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-Parent</artifactId>
<version>0.0.1-beta</version>
<version>0.2</version>
</parent>
<build>
@ -30,53 +30,6 @@
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/bin/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@ -93,12 +46,13 @@
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<finalName>${artifactId}</finalName>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>package</phase>
@ -108,7 +62,7 @@
</execution>
</executions>
<configuration>
<outputDirectory>${project.parent.basedir}/bin</outputDirectory>
<outputDirectory>${project.build.directory}/bin</outputDirectory>
<archive>
<manifest>
<mainClass>extensions.blockreplacepackets.BlockAndReplacePackets</mainClass>
@ -117,7 +71,7 @@
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>BlockAndReplacePackets</finalName>
<finalName>${project.artifactId}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
@ -127,8 +81,8 @@
<dependencies>
<dependency>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-UI</artifactId>
<version>0.0.1-beta</version>
<artifactId>G-Earth</artifactId>
<version>0.2</version>
<!--<scope>provided</scope>-->
</dependency>
</dependencies>

View File

@ -1,23 +1,38 @@
package extensions.blockreplacepackets;
import extensions.blockreplacepackets.rules.BlockReplaceRule;
import extensions.blockreplacepackets.rules.RuleFactory;
import gearth.extensions.Extension;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.ui.GEarthController;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import gearth.extensions.ExtensionForm;
import gearth.extensions.ExtensionInfo;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Jonas on 22/09/18.
*/
@ExtensionInfo(
Title = "iManipulate",
Title = "G-Manipulate",
Description = "Block &/ replace packets",
Version = "0.1",
Author = "sirjonasxx"
@ -26,32 +41,179 @@ public class BlockAndReplacePackets extends ExtensionForm {
public TextField txt_replacement;
public ComboBox<String> cmb_type;
public TextField txt_id;
public Button btn_add;
public volatile ComboBox<String> cmb_side;
public TextField txt_value;
public ScrollPane scrollpane;
public VBox vbox;
public GridPane header;
List<BlockReplaceRule> rules = new ArrayList<>();
public static void main(String[] args) {
ExtensionForm.args = args;
launch(args);
runExtensionForm(args, BlockAndReplacePackets.class);
}
//initialize javaFX elements
public void initialize() {
cmb_type.getItems().addAll("Block OUT", "Block IN", "Replace OUT", "Replace IN");
cmb_type.getItems().addAll("Block packet", "Replace packet", "Replace integer", "Replace string", "Replace substring");
cmb_type.getSelectionModel().selectFirst();
cmb_side.getItems().addAll("Incoming", "Outgoing");
cmb_side.getSelectionModel().selectFirst();
cmb_side.getSelectionModel().selectedItemProperty().addListener(observable -> Platform.runLater(this::refreshOptions));
cmb_type.getSelectionModel().selectedItemProperty().addListener(observable -> Platform.runLater(this::refreshOptions));
txt_replacement.textProperty().addListener(event -> Platform.runLater(this::refreshOptions));
txt_value.textProperty().addListener(event -> Platform.runLater(this::refreshOptions));
refreshOptions();
cmb_type.requestFocus();
}
private void refreshOptions() {
txt_replacement.setDisable(cmb_type.getSelectionModel().getSelectedItem().startsWith("Block"));
if (cmb_side.getItems().size() == 2 && !cmb_type.getSelectionModel().getSelectedItem().endsWith("packet")) {
cmb_side.getItems().add("All");
}
else if (cmb_side.getItems().size() == 3 && cmb_type.getSelectionModel().getSelectedItem().endsWith("packet")) {
if (cmb_side.getSelectionModel().getSelectedItem() != null && cmb_side.getSelectionModel().getSelectedItem().equals("All")) {
cmb_side.getSelectionModel().selectFirst();
}
cmb_side.getItems().remove(2);
}
boolean isValid = false;
String val = txt_value.getText();
String repl = txt_replacement.getText();
String type = cmb_type.getSelectionModel().getSelectedItem();
String side = cmb_side.getSelectionModel().getSelectedItem();
if (side == null) {
isValid = false;
}
else if (type.equals("Block packet")) {
try {
int v = Integer.parseInt(val);
isValid = (v < (Short.MAX_VALUE * 2 + 2) && v > 0);
}
catch (Exception e) {
isValid = false;
}
}
else {
if (type.endsWith("packet")) {
try {
int v = Integer.parseInt(val);
isValid = (v < (Short.MAX_VALUE * 2 + 2) && v > 0);
if (isValid) {
HPacket packet = new HPacket(repl);
isValid = !packet.isCorrupted();
}
}
catch (Exception e) {
isValid = false;
}
}
else if (type.endsWith("string")) {
isValid = !val.equals("") && !repl.equals("") && !val.equals(repl);
}
else if (type.endsWith("integer")) {
try {
int v1 = Integer.parseInt(val);
int v2 = Integer.parseInt(repl);
isValid = (v1 != v2);
}
catch (Exception e) {
isValid = false;
}
}
}
btn_add.setDisable(!isValid);
String[] spl = type.split(" ");
if (repl.equals("") && spl[0].equals("Replace")) {
if (spl[1].equals("packet")) {
txt_replacement.setPromptText("Enter a packet here");
}
else if (spl[1].equals("integer")) {
txt_replacement.setPromptText("Enter an integer here");
}
else if (spl[1].endsWith("string")) {
txt_replacement.setPromptText("Enter a string here");
}
}
else {
txt_replacement.setPromptText("");
}
if (val.equals("")) {
if (spl[1].equals("packet")) {
txt_value.setPromptText("Enter the headerID");
}
else if (spl[1].equals("integer")) {
txt_value.setPromptText("Enter an integer");
}
else if (spl[1].endsWith("string")) {
txt_value.setPromptText("Enter a string");
}
}
else {
txt_value.setPromptText("");
}
}
private void clearInput() {
txt_value.clear();
txt_replacement.clear();
refreshOptions();
cmb_type.requestFocus();
}
@Override
protected void initExtension() {
Extension.MessageListener messageListener = message -> {
for (BlockReplaceRule rule : rules) {
rule.appendRuleToMessage(message);
}
};
intercept(HMessage.Side.TOSERVER, messageListener);
intercept(HMessage.Side.TOCLIENT, messageListener);
}
@Override
public void setStageData(Stage primaryStage) throws Exception {
public ExtensionForm launchForm(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(BlockAndReplacePackets.class.getResource("blockreplace.fxml"));
Parent root = loader.load();
primaryStage.setTitle("Packet blocker &/ replacer");
primaryStage.setScene(new Scene(root, 580, 262));
primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("bootstrap3.css").toExternalForm());
primaryStage.setScene(new Scene(root));
primaryStage.setResizable(false);
primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("/gearth/ui/bootstrap3.css").toExternalForm());
return loader.getController();
}
@Override
protected void onShow() {
Platform.runLater(() -> cmb_type.requestFocus());
}
public void click_btnAddRule(ActionEvent actionEvent) {
BlockReplaceRule rule = RuleFactory.getRule(cmb_type.getSelectionModel().getSelectedItem(), cmb_side.getSelectionModel().getSelectedItem(), txt_value.getText(), txt_replacement.getText());
rules.add(rule);
rule.onDelete(observable -> rules.remove(rule));
new RuleContainer(rule, vbox);
clearInput();
}
@Override
protected boolean canDelete() {
return false;
}
}

View File

@ -0,0 +1,91 @@
package extensions.blockreplacepackets;
import extensions.blockreplacepackets.rules.BlockReplaceRule;
import gearth.ui.buttons.DeleteButton;
import gearth.ui.scheduler.ScheduleItem;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
/**
* Created by Jeunez on 6/11/2018.
*/
public class RuleContainer extends GridPane {
public static final int[] columnWidths = {12, 14, 18, 33, 15, 6};
VBox parent;
BlockReplaceRule item;
RuleContainer(BlockReplaceRule item, VBox parent) {
super();
this.parent = parent;
this.item = item;
setGridLinesVisible(true);
VBox.setMargin(this, new Insets(2, -2, -2, -2));
setPrefWidth(parent.getWidth());
setPrefHeight(23);
initialize();
}
private void initialize() {
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]);
getColumnConstraints().add(columnConstraints);
}
Label optionLabel = initNewLabelColumn(item.option().name());
Label typeLabel = initNewLabelColumn(item.type().name());
Label valueLabel = initNewLabelColumn(item.value());
Label replacementLabel = initNewLabelColumn(item.replacement());
Label destinationLabel = initNewLabelColumn(item.side().name());
add(optionLabel, 0, 0);
add(typeLabel, 1, 0);
add(valueLabel, 2, 0);
add(replacementLabel, 3, 0);
add(destinationLabel, 4, 0);
DeleteButton deleteButton = new DeleteButton();
deleteButton.setAlignment(Pos.CENTER);
deleteButton.show();
RuleContainer thiss = this;
item.onDelete(observable -> parent.getChildren().remove(thiss));
deleteButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.delete());
add(deleteButton, 5, 0);
parent.getChildren().add(this);
}
private Label initNewLabelColumn(String text) {
Label label = new Label();
// label.setMaxWidth(Double.MAX_VALUE);
// label.setMinHeight(Double.MAX_VALUE);
// label.setAlignment(Pos.CENTER);
label.setFont(new Font(12));
GridPane.setMargin(label, new Insets(0, 0, 0, 5));
label.setText(text);
return label;
}
}

View File

@ -4,73 +4,144 @@
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<TabPane prefHeight="255.0" prefWidth="580.0" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="extensions.blockreplacepackets.BlockAndReplacePackets">
<tabs>
<Tab text="Block/replace packet">
<content>
<GridPane>
<GridPane prefHeight="324.0" prefWidth="588.0" style="-fx-background-color: #FFFFFF;" xmlns="http://javafx.com/javafx/8.0.131" xmlns:fx="http://javafx.com/fxml/1" fx:controller="extensions.blockreplacepackets.BlockAndReplacePackets">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="209.0" minHeight="10.0" prefHeight="187.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="363.0" minHeight="10.0" prefHeight="35.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="276.0" minHeight="10.0" prefHeight="249.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane prefHeight="30.0" prefWidth="500.0" GridPane.rowIndex="1">
<GridPane GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="118.0" minWidth="10.0" prefWidth="28.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="291.0" minWidth="0.0" prefWidth="68.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="291.0" minWidth="0.0" prefWidth="124.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="246.0" minWidth="10.0" prefWidth="246.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="91.0" minWidth="10.0" prefWidth="68.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="464.0" minWidth="10.0" prefWidth="464.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="283.0" minWidth="10.0" prefWidth="116.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Button fx:id="btn_add" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Add" GridPane.columnIndex="4">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</Button>
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Id:" textAlignment="CENTER" textFill="#000000ba" />
<TextField fx:id="txt_id" GridPane.columnIndex="1">
<GridPane maxHeight="1.7976931348623157E308">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<children>
<GridPane prefHeight="41.0" prefWidth="580.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="191.0" minWidth="10.0" prefWidth="139.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="346.0" minWidth="10.0" prefWidth="50.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="148.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="314.0" minWidth="10.0" prefWidth="110.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="52.0" prefWidth="78.0" text="Value:" GridPane.columnIndex="1" />
<TextField fx:id="txt_value" prefHeight="25.0" prefWidth="106.0" GridPane.columnIndex="2">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
<ComboBox fx:id="cmb_type" maxWidth="1.7976931348623157E308" GridPane.columnIndex="2">
<ComboBox fx:id="cmb_type" maxWidth="1.7976931348623157E308">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</ComboBox>
<TextField fx:id="txt_replacement" disable="true" GridPane.columnIndex="3">
<ComboBox fx:id="cmb_side" maxWidth="1.7976931348623157E308" GridPane.columnIndex="3">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</ComboBox>
</children>
<GridPane.margin>
<Insets right="10.0" />
</GridPane.margin>
</GridPane>
<GridPane prefHeight="45.0" prefWidth="546.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="153.0" minWidth="10.0" prefWidth="88.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="373.0" minWidth="10.0" prefWidth="366.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" />
</rowConstraints>
<children>
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="32.0" prefWidth="99.0" text="Replace with:" />
<TextField fx:id="txt_replacement" disable="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
</children>
<GridPane.margin>
<Insets bottom="10.0" left="17.0" right="17.0" />
<Insets bottom="10.0" right="10.0" />
</GridPane.margin>
</GridPane>
</children>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="39.0" prefHeight="47.0" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="41.0" prefHeight="41.0" />
</rowConstraints>
<GridPane.margin>
<Insets />
</GridPane.margin>
</GridPane>
</content>
</Tab>
<Tab text="Block/replace value">
<Button fx:id="btn_add" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#click_btnAddRule" text="Add" GridPane.columnIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" top="5.0" />
</GridPane.margin>
</Button>
</children>
<GridPane.margin>
<Insets bottom="5.0" />
</GridPane.margin>
</GridPane>
<ScrollPane fx:id="scrollpane" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-background: #FFFFFF; -fx-border-radius: 4px;" vbarPolicy="ALWAYS">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
<VBox fx:id="vbox" maxHeight="1.7976931348623157E308" prefWidth="574.0">
<children>
<GridPane fx:id="header" gridLinesVisible="true">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="163.0" minWidth="10.0" percentWidth="12.0" prefWidth="57.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="190.0" minWidth="10.0" percentWidth="14.0" prefWidth="189.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="118.0" minWidth="10.0" percentWidth="18.0" prefWidth="66.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="33.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="6.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</VBox.margin>
<children>
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Option" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Type" GridPane.columnIndex="1" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Value" GridPane.columnIndex="2" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Replacement" GridPane.columnIndex="3" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Destination" GridPane.columnIndex="4" />
<Label alignment="CENTER" layoutX="564.0" layoutY="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text=" " GridPane.columnIndex="5" />
</children>
</GridPane>
</children>
</VBox>
</content>
</Tab>
</tabs>
</TabPane>
<GridPane.margin>
<Insets bottom="8.0" />
</GridPane.margin>
</ScrollPane>
</children>
<padding>
<Insets left="10.0" right="10.0" top="8.0" />
</padding>
</GridPane>

View File

@ -0,0 +1,54 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
/**
* Created by Jonas on 6/11/2018.
*/
public class BlockPacketRule extends BlockReplaceRule{
private int headerId;
private Side side;
BlockPacketRule(Side side, int headerId) {
this.headerId = headerId;
this.side = side;
}
@Override
public void appendRuleToMessage(HMessage message) {
if (side == Side.ALL
|| (message.getDestination() == HMessage.Side.TOSERVER && side == Side.OUTGOING)
|| (message.getDestination() == HMessage.Side.TOCLIENT && side ==Side.INCOMING)) {
if (message.getPacket().headerId() == headerId) {
message.setBlocked(true);
}
}
}
@Override
public Option option() {
return Option.BLOCK;
}
@Override
public Type type() {
return Type.PACKET;
}
@Override
public Side side() {
return side;
}
@Override
public String value() {
return headerId+"";
}
@Override
public String replacement() {
return "/";
}
}

View File

@ -0,0 +1,52 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
import javafx.beans.InvalidationListener;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Jonas on 6/11/2018.
*/
public abstract class BlockReplaceRule {
public enum Option {
BLOCK,
REPLACE
}
public enum Type {
PACKET,
INTEGER,
STRING,
SUBSTRING
}
public enum Side {
INCOMING,
OUTGOING,
ALL
}
public abstract void appendRuleToMessage(HMessage message);
public abstract Option option();
public abstract Type type();
public abstract Side side();
public abstract String value();
public abstract String replacement();
private List<InvalidationListener> onDeleteListeners = new ArrayList<>();
public void onDelete(InvalidationListener listener) {
onDeleteListeners.add(listener);
}
public void delete() {
for (int i = onDeleteListeners.size() - 1; i >= 0; i--) {
onDeleteListeners.get(i).invalidated(null);
}
}
}

View File

@ -0,0 +1,53 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
/**
* Created by Jonas on 6/11/2018.
*/
public class ReplaceIntegerRule extends BlockReplaceRule {
Side side;
int value;
int replacement;
ReplaceIntegerRule(Side side, int value, int replacement) {
this.side = side;
this.value = value;
this.replacement = replacement;
}
@Override
public void appendRuleToMessage(HMessage message) {
if (side == Side.ALL
|| (message.getDestination() == HMessage.Side.TOSERVER && side == Side.OUTGOING)
|| (message.getDestination() == HMessage.Side.TOCLIENT && side ==Side.INCOMING)) {
message.getPacket().replaceAllIntegers(value, replacement);
}
}
@Override
public Option option() {
return Option.REPLACE;
}
@Override
public Type type() {
return Type.INTEGER;
}
@Override
public Side side() {
return side;
}
@Override
public String value() {
return value+"";
}
@Override
public String replacement() {
return replacement+"";
}
}

View File

@ -0,0 +1,57 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
/**
* Created by Jeunez on 6/11/2018.
*/
public class ReplacePacketRule extends BlockReplaceRule {
private Side side;
private int headerId;
private HPacket replacement;
ReplacePacketRule(Side side, int headerId, HPacket replacement) {
this.side = side;
this.headerId = headerId;
this.replacement = replacement;
}
@Override
public void appendRuleToMessage(HMessage message) {
if (side == Side.ALL
|| (message.getDestination() == HMessage.Side.TOSERVER && side == Side.OUTGOING)
|| (message.getDestination() == HMessage.Side.TOCLIENT && side ==Side.INCOMING)) {
if (message.getPacket().headerId() == headerId) {
message.getPacket().constructFromString(replacement.stringify());
message.getPacket().overrideEditedField(true);
}
}
}
@Override
public Option option() {
return Option.REPLACE;
}
@Override
public Type type() {
return Type.PACKET;
}
@Override
public Side side() {
return side;
}
@Override
public String value() {
return headerId+"";
}
@Override
public String replacement() {
return replacement.toString();
}
}

View File

@ -0,0 +1,53 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
/**
* Created by Jonas on 6/11/2018.
*/
public class ReplaceStringRule extends BlockReplaceRule {
private Side side;
private String value;
private String replacement;
ReplaceStringRule(Side side, String value, String replacement) {
this.side = side;
this.value = value;
this.replacement = replacement;
}
@Override
public void appendRuleToMessage(HMessage message) {
if (side == Side.ALL
|| (message.getDestination() == HMessage.Side.TOSERVER && side == Side.OUTGOING)
|| (message.getDestination() == HMessage.Side.TOCLIENT && side ==Side.INCOMING)) {
message.getPacket().replaceAllStrings(value, replacement);
}
}
@Override
public Option option() {
return Option.REPLACE;
}
@Override
public Type type() {
return Type.STRING;
}
@Override
public Side side() {
return side;
}
@Override
public String value() {
return value;
}
@Override
public String replacement() {
return replacement;
}
}

View File

@ -0,0 +1,53 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
/**
* Created by Jonas on 6/11/2018.
*/
public class ReplaceSubstringRule extends BlockReplaceRule {
private Side side;
private String value;
private String replacement;
ReplaceSubstringRule(Side side, String value, String replacement) {
this.side = side;
this.value = value;
this.replacement = replacement;
}
@Override
public void appendRuleToMessage(HMessage message) {
if (side == Side.ALL
|| (message.getDestination() == HMessage.Side.TOSERVER && side == Side.OUTGOING)
|| (message.getDestination() == HMessage.Side.TOCLIENT && side ==Side.INCOMING)) {
message.getPacket().replaceAllSubstrings(value, replacement);
}
}
@Override
public Option option() {
return Option.REPLACE;
}
@Override
public Type type() {
return Type.SUBSTRING;
}
@Override
public Side side() {
return side;
}
@Override
public String value() {
return value;
}
@Override
public String replacement() {
return replacement;
}
}

View File

@ -0,0 +1,35 @@
package extensions.blockreplacepackets.rules;
import gearth.protocol.HPacket;
/**
* Created by Jonas on 6/11/2018.
*/
public class RuleFactory {
public static BlockReplaceRule getRule(String type, String side, String value, String replacement) {
BlockReplaceRule.Option rOption = BlockReplaceRule.Option.valueOf(type.split(" ")[0].toUpperCase());
BlockReplaceRule.Type rType = BlockReplaceRule.Type.valueOf(type.split(" ")[1].toUpperCase());
BlockReplaceRule.Side rSide = BlockReplaceRule.Side.valueOf(side.toUpperCase());
if (rOption == BlockReplaceRule.Option.BLOCK) {
return new BlockPacketRule(rSide, Integer.parseInt(value));
}
if (rOption == BlockReplaceRule.Option.REPLACE) {
if (rType == BlockReplaceRule.Type.INTEGER) {
return new ReplaceIntegerRule(rSide, Integer.parseInt(value), Integer.parseInt(replacement));
}
if (rType == BlockReplaceRule.Type.PACKET) {
return new ReplacePacketRule(rSide, Integer.parseInt(value), new HPacket(replacement));
}
if (rType == BlockReplaceRule.Type.STRING) {
return new ReplaceStringRule(rSide, value, replacement);
}
if (rType == BlockReplaceRule.Type.SUBSTRING) {
return new ReplaceSubstringRule(rSide, value, replacement);
}
}
return null;
}
}

View File

@ -13,7 +13,7 @@
<parent>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-Parent</artifactId>
<version>0.0.1-beta</version>
<version>0.2</version>
</parent>
<build>
@ -30,53 +30,6 @@
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/bin/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@ -93,12 +46,13 @@
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
<finalName>${artifactId}</finalName>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>package</phase>
@ -108,7 +62,7 @@
</execution>
</executions>
<configuration>
<outputDirectory>${project.parent.basedir}/target/bin</outputDirectory>
<outputDirectory>${project.build.directory}/bin</outputDirectory>
<archive>
<manifest>
<mainClass>extensions.speechcolorizer.SpeechColorizer</mainClass>
@ -117,6 +71,8 @@
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${project.artifactId}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
</plugins>
@ -125,8 +81,8 @@
<dependencies>
<dependency>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-UI</artifactId>
<version>0.0.1-beta</version>
<artifactId>G-Earth</artifactId>
<version>0.2</version>
<!--<scope>provided</scope>-->
</dependency>
</dependencies>

View File

@ -12,8 +12,7 @@ import java.util.Random;
*/
/**
* - getTitle(), getDescription(), getVersion() and getAuthor() must be implemented
*
* This is an example extension and is not included in a G-Earth release
*/
@ExtensionInfo(

View File

@ -1,43 +0,0 @@
package gearth;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import gearth.ui.GEarthController;
// run as root issue Invalid MIT-MAGIC-COOKIE-1 key fix: https://stackoverflow.com/questions/48139447/invalid-mit-magic-cookie-1-key
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader(GEarthController.class.getResource("G-Earth.fxml"));
Parent root = loader.load();
GEarthController companion = loader.getController();
companion.setStage(primaryStage);
primaryStage.setResizable(false);
//primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setTitle("G-Earth");
primaryStage.setScene(new Scene(root, 620, 295));
primaryStage.show();
primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("bootstrap3.css").toExternalForm());
primaryStage.setOnCloseRequest( event -> {
companion.abort();
Platform.exit();
});
}
public static String[] args;
public static void main(String[] args) {
Main.args = args;
launch(args);
}
}

View File

@ -1,114 +0,0 @@
package gearth.extensions;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
/**
* Created by Jonas on 22/09/18.
*/
public abstract class ExtensionForm extends Application {
private Extension extension = null;
protected static String[] args;
private volatile Stage primaryStage = null;
@Override
public void start(Stage primaryStage) throws Exception {
Platform.setImplicitExit(false);
setStageData(primaryStage);
this.primaryStage = primaryStage;
primaryStage.setOnCloseRequest(event -> {
event.consume();
Platform.runLater(primaryStage::hide);
});
ExtensionForm thiss = this;
ExtensionInfo extInfo = getClass().getAnnotation(ExtensionInfo.class);
Thread t = new Thread(() -> {
extension = new Extension(args) {
@Override
protected void init() {
thiss.initExtension();
}
@Override
protected void onClick() {
thiss.onClick();
}
@Override
protected void onStartConnection() {
thiss.onStartConnection();
}
@Override
protected void onEndConnection() {
thiss.onEndConnection();
}
@Override
ExtensionInfo getInfoAnnotations() {
return extInfo;
}
};
extension.run();
// Platform.runLater(primaryStage::close);
//when the extension has ended, close this process
Platform.exit();
});
t.start();
}
public abstract void setStageData(Stage primaryStage) throws Exception;
//wrap extension methods
protected boolean requestFlags(Extension.FlagsCheckListener flagRequestCallback){
return extension.requestFlags(flagRequestCallback);
}
protected void writeToConsole(String s) {
extension.writeToConsole(s);
}
protected void intercept(HMessage.Side side, Extension.MessageListener messageListener) {
extension.intercept(side, messageListener);
}
protected void intercept(HMessage.Side side, int headerId, Extension.MessageListener messageListener){
extension.intercept(side, headerId, messageListener);
}
protected boolean sendToServer(HPacket packet){
return extension.sendToServer(packet);
}
protected boolean sendToClient(HPacket packet){
return extension.sendToClient(packet);
}
/**
* Gets called when a connection has been established with G-Earth.
* This does not imply a connection with Habbo is setup.
*/
protected void initExtension(){}
/**
* The application got doubleclicked from the G-Earth interface. Doing something here is optional
*/
private void onClick(){
Platform.runLater(() -> {
primaryStage.show();
});
}
/**
* A connection with Habbo has been started
*/
protected void onStartConnection(){}
/**
* A connection with Habbo has ended
*/
protected void onEndConnection(){}
}

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<!--maxHeight="19.0" minHeight="19.0"-->
<VBox xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.GEarthController">
<Pane fx:id="mover" maxHeight="0.0" minHeight="0.0" prefWidth="200.0" />
<TabPane fx:id="tabBar" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="295.0" prefWidth="565.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Connection">
<content>
<fx:include fx:id="connection" source="connection/Connection.fxml" />
</content>
</Tab>
<Tab text="Logger">
<content>
<fx:include fx:id="logger" source="logger/Logger.fxml" />
</content></Tab>
<Tab text="Injection">
<content>
<fx:include fx:id="injection" source="injection/Injection.fxml" />
</content></Tab>
<Tab text="Tools">
<content>
<fx:include fx:id="tools" source="tools/Tools.fxml" />
</content>
</Tab>
<Tab text="Scheduler">
<content>
<fx:include fx:id="scheduler" source="scheduler/Scheduler.fxml" />
</content>
</Tab>
<Tab fx:id="tab_Settings" text="Settings">
<content>
<fx:include fx:id="settings" source="settings/Settings.fxml" />
</content>
</Tab>
<Tab text="Extensions">
<content>
<fx:include fx:id="extensions" source="extensions/Extensions.fxml" />
</content>
</Tab>
<Tab text="Info">
<content>
<fx:include fx:id="info" source="info/Info.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
</VBox>

View File

@ -1,207 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.connection.Connection">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="172.0" minHeight="10.0" prefHeight="140.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="127.0" minHeight="10.0" prefHeight="122.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane alignment="CENTER" GridPane.hgrow="SOMETIMES" GridPane.vgrow="SOMETIMES">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="483.0" minWidth="10.0" prefWidth="317.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="350.0" minWidth="10.0" prefWidth="248.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane GridPane.columnIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="32.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="40.0" minHeight="10.0" prefHeight="37.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="45.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="45.0" minHeight="10.0" prefHeight="21.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="120.0" minWidth="10.0" prefWidth="68.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="188.0" minWidth="10.0" prefWidth="184.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpPort" disable="true" editable="true" prefWidth="183.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
</ComboBox>
</children>
</GridPane>
<GridPane layoutX="10.0" layoutY="10.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="120.0" minWidth="10.0" prefWidth="68.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="188.0" minWidth="10.0" prefWidth="184.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpHost" disable="true" editable="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
</ComboBox>
</children>
</GridPane>
<GridPane GridPane.rowIndex="2">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="185.0" minWidth="10.0" prefWidth="158.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="117.0" minWidth="10.0" prefWidth="90.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<children>
<CheckBox fx:id="cbx_autodetect" mnemonicParsing="false" selected="true" text="Auto-detect" textFill="#000000a9" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets left="-5.0" />
</GridPane.margin>
<font>
<Font size="12.0" />
</font>
</CheckBox>
<Button fx:id="btnConnect" alignment="CENTER" maxWidth="1.7976931348623157E308" onAction="#btnConnect_clicked" text="Connect" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets left="15.0" right="15.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets top="20.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="14.0" left="20.0" right="15.0" top="17.0" />
</GridPane.margin>
</GridPane>
</children>
</GridPane>
<GridPane alignment="CENTER" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="340.0" minWidth="10.0" prefWidth="208.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="380.0" minWidth="10.0" prefWidth="357.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="62.0" minHeight="10.0" prefHeight="53.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="107.0" minHeight="10.0" prefHeight="85.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Connection state:" textFill="#000000ba" GridPane.valignment="BOTTOM">
<GridPane.margin>
<Insets bottom="5.0" left="2.0" />
</GridPane.margin>
<font>
<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">
<GridPane.margin>
<Insets />
</GridPane.margin></Label>
</children>
<GridPane.margin>
<Insets bottom="14.0" left="20.0" right="20.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px; " GridPane.columnIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="140.0" minWidth="10.0" prefWidth="103.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="191.0" minWidth="10.0" prefWidth="190.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="12.0" left="20.0" right="10.0" top="12.0" />
</GridPane.margin>
<children>
<Label text="Game host:" textFill="#000000cc">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<Label 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">
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="outPort" editable="false" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
</children>
<padding>
<Insets bottom="7.0" top="7.0" />
</padding>
</GridPane>
</children>
<GridPane.margin>
<Insets />
</GridPane.margin>
</GridPane>
</children>
</GridPane>

View File

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.extensions.Extensions">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="277.0" />
</columnConstraints>
<rowConstraints>
<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>
<children>
<ScrollPane fx:id="scroller" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-background: #FFFFFF; -fx-border-radius: 4px;" vbarPolicy="ALWAYS">
<GridPane.margin>
<Insets bottom="8.0" left="17.0" right="17.0" top="17.0" />
</GridPane.margin>
<content>
<VBox fx:id="extensioncontainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<children>
<GridPane fx:id="header_ext" gridLinesVisible="true">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="163.0" minWidth="10.0" percentWidth="22.0" prefWidth="57.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="190.0" minWidth="10.0" percentWidth="34.0" prefWidth="189.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="118.0" minWidth="10.0" percentWidth="18.0" prefWidth="66.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="13.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="11.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Title" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Description" GridPane.columnIndex="1" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Author" GridPane.columnIndex="2" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Version" GridPane.columnIndex="3" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" />
</children>
<VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</VBox.margin>
</GridPane>
</children></VBox>
</content>
</ScrollPane>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" vgap="3.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="349.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="10.0" left="17.0" right="17.0" />
</GridPane.margin>
<children>
<GridPane hgap="7.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="63.0" minWidth="49.0" prefWidth="49.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="114.0" minWidth="10.0" prefWidth="101.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="257.0" minWidth="70.0" prefWidth="247.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="35.0" prefWidth="113.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TextField fx:id="ext_port" editable="false" prefHeight="26.0" prefWidth="157.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets left="-7.0" />
</GridPane.margin>
</TextField>
<Label maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Port:" textFill="#000000bb">
<GridPane.margin>
<Insets left="3.0" />
</GridPane.margin>
</Label>
<Button fx:id="btn_install" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#installBtnClicked" text="Install" GridPane.columnIndex="3" />
</children>
</GridPane>
</children>
</GridPane>
</children>
</GridPane>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.info.Info">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="367.0" minWidth="10.0" prefWidth="332.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="10.0" prefWidth="233.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TextArea fx:id="text" editable="false" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</GridPane.margin>
</TextArea>
</children>
</GridPane>

View File

@ -1,42 +0,0 @@
package gearth.ui.info;
import javafx.scene.control.TextArea;
import gearth.ui.SubForm;
/**
* Created by Jonas on 06/04/18.
*/
public class Info extends SubForm {
public TextArea text;
// this is a TEMPORARY info tab
public void initialize() {
String[] lines = {
"G-Earth 0.1.1",
"Linux Habbo Packet Manipulator",
"",
"Made by:",
"sirjonasxx",
"",
"Contributors:",
"XePeleato (Windows & Mac support)",
"LittleJ",
"ArachisH",
"",
"Check out:",
"sngforum.info",
"darkbox.nl"
};
String all = lines[0];
for (int i = 1; i < lines.length; i++) {
all += (System.lineSeparator() + lines[i]);
}
text.setText(
all
);
}
}

View File

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.injection.Injection">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="232.0" minHeight="10.0" prefHeight="36.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="232.0" minHeight="10.0" prefHeight="194.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="121.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane GridPane.rowIndex="0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Text fx:id="lbl_corrruption" fill="#ee0404b2" strokeType="OUTSIDE" strokeWidth="0.0" 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" text="header (id:NULL, length:0)" GridPane.columnIndex="1" GridPane.halignment="RIGHT">
<font>
<Font name="System Italic" size="11.0" />
</font>
</Text>
</children>
<GridPane.margin>
<Insets left="13.0" right="13.0" top="4.0" />
</GridPane.margin>
</GridPane>
<TextArea fx:id="inputPacket" 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>
</TextArea>
<GridPane GridPane.rowIndex="2">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<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">
<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">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
</children>
<padding>
<Insets bottom="7.0" />
</padding>
</GridPane>

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.TextFlow?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.logger.Logger">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="293.0" minWidth="10.0" prefWidth="242.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="10.0" prefWidth="323.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5.0E9" prefWidth="5.0E9">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="138.0" minHeight="10.0" prefHeight="126.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="111.0" minHeight="10.0" prefHeight="109.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
<children>
<GridPane prefHeight="52.0" prefWidth="214.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="160.0" minWidth="10.0" prefWidth="132.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="10.0" prefWidth="84.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Packet size limit:" />
<TextField fx:id="txtPacketLimit" text="8000" GridPane.rowIndex="1">
<GridPane.margin>
<Insets right="8.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
<Button fx:id="btnUpdate" 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" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<GridPane.margin>
<Insets bottom="-1.0" left="6.0" right="6.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
<CheckBox fx:id="cbx_blockIn" mnemonicParsing="false" text="Block Incoming" />
<CheckBox fx:id="cbx_blockOut" mnemonicParsing="false" text="Block Outgoing" />
</children>
</VBox>
<VBox alignment="BOTTOM_LEFT" prefHeight="99.0" prefWidth="198.0" spacing="8.0" GridPane.rowIndex="1">
<children>
<CheckBox fx:id="cbx_showAdditional" mnemonicParsing="false" selected="true" text="Show additional data" />
<CheckBox fx:id="cbx_showstruct" mnemonicParsing="false" selected="true" text="Show packet structure" />
<CheckBox fx:id="cbx_splitPackets" mnemonicParsing="false" selected="true" text="Split packets" />
</children>
<GridPane.margin>
<Insets />
</GridPane.margin>
</VBox>
</children>
<GridPane.margin>
<Insets bottom="12.0" left="17.0" top="15.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888; -fx-border-radius: 5px;" GridPane.columnIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="125.0" minHeight="10.0" prefHeight="33.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="233.0" minHeight="10.0" prefHeight="191.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<CheckBox fx:id="cbx_useLog" mnemonicParsing="false" selected="true" text="Use history log">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</CheckBox>
<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;">
<GridPane.margin>
<Insets />
</GridPane.margin>
</TextFlow>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</ScrollPane>
</children>
<GridPane.margin>
<Insets bottom="10.0" left="15.0" right="15.0" top="10.0" />
</GridPane.margin>
<padding>
<Insets bottom="10.0" left="7.0" right="7.0" top="6.0" />
</padding>
</GridPane>
</children>
</GridPane>

View File

@ -1,141 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.scheduler.Scheduler">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="277.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="220.0" minHeight="10.0" prefHeight="183.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="185.0" minHeight="10.0" prefHeight="79.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ScrollPane fx:id="scrollpane" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-background: #FFFFFF; -fx-border-radius: 4px;" vbarPolicy="ALWAYS">
<GridPane.margin>
<Insets bottom="8.0" left="17.0" right="17.0" top="17.0" />
</GridPane.margin>
<content>
<VBox fx:id="schedulecontainer" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<children>
<GridPane fx:id="header" gridLinesVisible="true">
<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" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="118.0" minWidth="10.0" percentWidth="16.0" prefWidth="66.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="18.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="100.0" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Index" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Packet" GridPane.columnIndex="1" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Interval" GridPane.columnIndex="2" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Destination" GridPane.columnIndex="3" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-text-fill: #666666; -fx-background-color: #F7F7F7;" text="Edit" GridPane.columnIndex="4" />
</children>
<VBox.margin>
<Insets bottom="-2.0" left="-2.0" right="-2.0" top="-2.0" />
</VBox.margin>
</GridPane>
</children></VBox>
</content>
</ScrollPane>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" vgap="3.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="349.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="10.0" left="17.0" right="17.0" />
</GridPane.margin>
<children>
<GridPane hgap="7.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="63.0" minWidth="63.0" prefWidth="63.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="468.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="70.0" prefWidth="70.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="35.0" prefWidth="35.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="35.0" prefWidth="35.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TextField fx:id="txt_packet" text="[0][0][0][2][0][0]" GridPane.columnIndex="1">
<GridPane.margin>
<Insets left="-7.0" />
</GridPane.margin>
</TextField>
<Label 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="2" />
<Button fx:id="btn_save" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#saveBtnClicked" text="S" GridPane.columnIndex="3" />
<Button fx:id="btn_load" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#loadBtnClicked" text="L" GridPane.columnIndex="4" />
</children>
</GridPane>
<GridPane prefHeight="33.0" prefWidth="502.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="63.0" minWidth="0.0" prefWidth="63.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="488.0" minWidth="10.0" prefWidth="80.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="102.0" minWidth="10.0" prefWidth="102.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="107.0" minWidth="10.0" prefWidth="107.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="488.0" minWidth="10.0" prefWidth="181.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TextField fx:id="txt_delay" text="500+0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="5.0" />
</GridPane.margin>
</TextField>
<Label 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 to scheduler" 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="Incoming" GridPane.columnIndex="2">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
<toggleGroup>
<ToggleGroup fx:id="scheduler_dest" />
</toggleGroup></RadioButton>
<RadioButton fx:id="rb_outgoing" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Outgoing" toggleGroup="$scheduler_dest" GridPane.columnIndex="3">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></RadioButton>
</children>
<GridPane.margin>
<Insets />
</GridPane.margin>
</GridPane>
</children>
</GridPane>
</children>
</GridPane>

View File

@ -1,165 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.tools.Tools">
<rowConstraints>
<RowConstraints maxHeight="158.0" minHeight="10.0" prefHeight="134.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="141.0" minHeight="10.0" prefHeight="128.0" vgrow="SOMETIMES" />
</rowConstraints>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="683.0" minWidth="10.0" prefWidth="276.0" />
</columnConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="53.0" minHeight="10.0" prefHeight="29.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="108.0" minHeight="10.0" prefHeight="100.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="103.0" minWidth="10.0" prefWidth="73.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="159.0" minWidth="10.0" prefWidth="146.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="129.0" minWidth="10.0" prefWidth="89.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="148.0" minWidth="10.0" prefWidth="89.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="167.0" minWidth="10.0" prefWidth="146.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets />
</GridPane.margin>
<children>
<Label alignment="CENTER" text="Integer:">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<TextField fx:id="txt_intDecoded" 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" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnEncodeInt_clicked" 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" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnDecodeInt_clicked" 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" 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 alignment="CENTER" text="Ushort:" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<TextField fx:id="txt_ushortDecoded" 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" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnEncodeUShort_clicked" 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" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnDecodeUshort_clicked" 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" maxWidth="1.7976931348623157E308" GridPane.columnIndex="4" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
<Label text="Encoding/decoding" textFill="#000000cc">
<GridPane.margin>
<Insets left="6.0" top="5.0" />
</GridPane.margin>
<font>
<Font name="System Italic" size="12.0" />
</font>
</Label>
</children>
<GridPane.margin>
<Insets left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</GridPane>
<GridPane layoutX="20.0" layoutY="15.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="53.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="104.0" minHeight="10.0" prefHeight="99.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="190.0" minWidth="10.0" prefWidth="180.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="130.0" minWidth="10.0" prefWidth="90.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="118.0" minWidth="10.0" prefWidth="90.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="219.0" minWidth="10.0" prefWidth="180.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets />
</GridPane.margin>
<children>
<Button fx:id="btn_toExpr" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btn_toExpr_clicked" 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" 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" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btn_toPacket_clicked" 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" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true" GridPane.columnIndex="3" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="7.0" top="7.0" />
</GridPane.margin>
</TextArea>
</children>
</GridPane>
<Label text="Packet &lt;-&gt; expression" textFill="#000000cc">
<GridPane.margin>
<Insets left="6.0" top="2.0" />
</GridPane.margin>
<font>
<Font name="System Italic" size="12.0" />
</font>
</Label>
</children>
<GridPane.margin>
<Insets bottom="7.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</GridPane>
</children>
</GridPane>

View File

@ -4,80 +4,21 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>G-Earth-UI</artifactId>
<artifactId>G-Earth</artifactId>
<packaging>jar</packaging>
<version>0.0.1-beta</version>
<version>0.2</version>
<parent>
<groupId>G-Earth</groupId>
<artifactId>G-Earth-Parent</artifactId>
<version>0.0.1-beta</version>
<version>0.2</version>
</parent>
<build>
<resources>
<!-- Embedded FXML and CSS resources -->
<resource>
<filtering>false</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.fxml</include>
<include>**/*.css</include>
<include>**/*.png</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- this would copy dependencies if we were building a non-standalone JAR -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/bin/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- this builds a non-standalone JAR file -->
<plugin>
@ -100,6 +41,7 @@
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>package</phase>
@ -109,7 +51,7 @@
</execution>
</executions>
<configuration>
<outputDirectory>${project.parent.basedir}/bin</outputDirectory>
<outputDirectory>${project.build.directory}/bin</outputDirectory>
<archive>
<manifest>
<mainClass>gearth.Main</mainClass>
@ -136,5 +78,10 @@
<artifactId>richtextfx</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.2</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,124 @@
package gearth;
import gearth.misc.AdminValidator;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Region;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import gearth.ui.GEarthController;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.omg.CORBA.Environment;
import java.io.IOException;
// run as root issue Invalid MIT-MAGIC-COOKIE-1 key fix: https://stackoverflow.com/questions/48139447/invalid-mit-magic-cookie-1-key
public class Main extends Application {
public static Application main;
public static String version = "0.2";
private static String gitApi = "https://api.github.com/repos/sirjonasxx/G-Earth/releases/latest";
@Override
public void start(Stage primaryStage) throws Exception{
main = this;
FXMLLoader loader = new FXMLLoader(getClass().getResource("/gearth/ui/G-Earth.fxml"));
Parent root = loader.load();
GEarthController companion = loader.getController();
companion.setStage(primaryStage);
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/gearth/G-EarthLogoSmaller.png")));
primaryStage.setResizable(false);
//primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setTitle("G-Earth " + version);
primaryStage.setScene(new Scene(root, 620, 295));
primaryStage.show();
primaryStage.getScene().getStylesheets().add(getClass().getResource("/gearth/ui/bootstrap3.css").toExternalForm());
primaryStage.setOnCloseRequest( event -> {
companion.abort();
Platform.exit();
// Platform.exit doesn't seem to be enough on Windows?
System.exit(0);
});
new Thread(() -> {
if (!AdminValidator.isAdmin()) {
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.ERROR, "G-Earth needs admin privileges in order to work properly, please restart G-Earth with admin permissions unless you know what you're doing", ButtonType.OK);
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
alert.show();
});
}
}).start();
new Thread(() -> {
try {
String s = Jsoup.connect(gitApi).ignoreContentType(true).get().body().toString();
s = s.substring(6, s.length() - 7);
JSONObject object = new JSONObject(s);
String gitv = (String)object.get("tag_name");
if (!gitv.equals(version)) {
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.INFORMATION, "G-Earth is outdated!", ButtonType.OK);
FlowPane fp = new FlowPane();
Label lbl = new Label("A new version of G-Earth has been found ("+gitv+")" + System.lineSeparator()+ System.lineSeparator() + "Update to the latest version:");
Hyperlink link = new Hyperlink("https://github.com/sirjonasxx/G-Earth/releases");
fp.getChildren().addAll( lbl, link);
link.setOnAction(event -> {
Main.main.getHostServices().showDocument(link.getText());
event.consume();
});
WebView webView = new WebView();
webView.getEngine().loadContent("<html>A new version of G-Earth has been found ("+gitv+")<br><br>Update to the latest version:<br><a href=\"https://github.com/sirjonasxx/G-Earth/releases\">https://github.com/sirjonasxx/G-Earth/releases</a></html>");
webView.setPrefSize(500, 200);
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
alert.getDialogPane().setContent(fp);
alert.show();
});
}
} catch (IOException e) {
// e.printStackTrace();
}
}).start();
}
public static String[] args;
public static void main(String[] args) {
Main.args = args;
launch(args);
}
public static boolean hasFlag(String flag) {
for(String s : args) {
if (s.equals(flag)) {
return true;
}
}
return false;
}
}

View File

@ -23,13 +23,14 @@ public abstract class Extension {
void act(String[] args);
}
protected static final boolean CANLEAVE = true; // can you disconnect the ext
protected static final boolean CANDELETE = true; // can you delete the ext (will be false for some built-in extensions)
protected boolean canLeave; // can you disconnect the ext
protected boolean canDelete; // can you delete the ext (will be false for some built-in extensions)
private String[] args;
private boolean isCorrupted = false;
private static final String[] PORT_FLAG = {"--port", "-p"};
private static final String[] FILE_FLAG = {"--filename", "-f"};
private static final String[] COOKIE_FLAG = {"--auth-token", "-c"}; // don't add a cookie or filename when debugging
private OutputStream out = null;
private final Map<Integer, List<MessageListener>> incomingMessageListeners = new HashMap<>();
@ -52,6 +53,9 @@ public abstract class Extension {
* @param args arguments
*/
public Extension(String[] args) {
canLeave = canLeave();
canDelete = canDelete();
//obtain port
this.args = args;
@ -81,6 +85,7 @@ public abstract class Extension {
int port = Integer.parseInt(getArgument(args, PORT_FLAG));
String file = getArgument(args, FILE_FLAG);
String cookie = getArgument(args, COOKIE_FLAG);
Socket gEarthExtensionServer = null;
try {
@ -123,8 +128,9 @@ public abstract class Extension {
.appendBoolean(isOnClickMethodUsed())
.appendBoolean(file != null)
.appendString(file == null ? "": file)
.appendBoolean(CANLEAVE)
.appendBoolean(CANDELETE);
.appendString(cookie == null ? "" : cookie)
.appendBoolean(canLeave)
.appendBoolean(canDelete);
writeToStream(response.toBytes());
}
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.CONNECTIONSTART) {
@ -183,10 +189,10 @@ public abstract class Extension {
}
for(MessageListener listener : correctListeners) {
habboMessage.getPacket().setReadIndex(6);
habboMessage.getPacket().resetReadIndex();
listener.act(habboMessage);
}
habboMessage.getPacket().setReadIndex(6);
habboMessage.getPacket().resetReadIndex();
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.MANIPULATEDPACKET);
response.appendLongString(habboMessage.stringify());
@ -345,6 +351,14 @@ public abstract class Extension {
*/
protected void onEndConnection(){}
protected boolean canLeave() {
return true;
}
protected boolean canDelete() {
return true;
}
ExtensionInfo getInfoAnnotations() {
return getClass().getAnnotation(ExtensionInfo.class);

View File

@ -0,0 +1,85 @@
package gearth.extensions;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import java.util.concurrent.Semaphore;
/**
* Created by Jonas on 22/09/18.
*/
public abstract class ExtensionForm {
volatile Extension extension;
volatile Stage primaryStage;
protected static void runExtensionForm(String[] args, Class<? extends ExtensionForm> extension) {
ExtensionFormLauncher launcher = new ExtensionFormLauncher();
launcher.trigger(extension, args);
}
public abstract ExtensionForm launchForm(Stage primaryStage) throws Exception;
//wrap extension methods
protected boolean requestFlags(Extension.FlagsCheckListener flagRequestCallback){
return extension.requestFlags(flagRequestCallback);
}
protected void writeToConsole(String s) {
extension.writeToConsole(s);
}
protected void intercept(HMessage.Side side, Extension.MessageListener messageListener) {
extension.intercept(side, messageListener);
}
protected void intercept(HMessage.Side side, int headerId, Extension.MessageListener messageListener){
extension.intercept(side, headerId, messageListener);
}
protected boolean sendToServer(HPacket packet){
return extension.sendToServer(packet);
}
protected boolean sendToClient(HPacket packet){
return extension.sendToClient(packet);
}
protected void onShow(){};
protected void onHide(){};
/**
* Gets called when a connection has been established with G-Earth.
* This does not imply a connection with Habbo is setup.
*/
protected void initExtension(){}
/**
* The application got doubleclicked from the G-Earth interface. Doing something here is optional
*/
protected void onClick(){
Platform.runLater(() -> {
primaryStage.show();
primaryStage.requestFocus();
primaryStage.toFront();
onShow();
});
}
/**
* A connection with Habbo has been started
*/
protected void onStartConnection(){}
/**
* A connection with Habbo has ended
*/
protected void onEndConnection(){}
protected boolean canLeave() {
return true;
}
protected boolean canDelete() {
return true;
}
}

View File

@ -0,0 +1,83 @@
package gearth.extensions;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
/**
* Created by Jeunez on 6/11/2018.
*/
public class ExtensionFormLauncher extends Application{
private static Class<? extends ExtensionForm> extension;
private static String[] args;
@Override
public void start(Stage primaryStage) throws Exception {
ExtensionInfo extInfo = extension.getAnnotation(ExtensionInfo.class);
ExtensionForm creator = extension.newInstance();
ExtensionForm extensionForm = creator.launchForm(primaryStage);
extensionForm.extension = new Extension(args) {
@Override
protected void init() {
extensionForm.initExtension();
}
@Override
protected void onClick() {
extensionForm.onClick();
}
@Override
protected void onStartConnection() {
extensionForm.onStartConnection();
}
@Override
protected void onEndConnection() {
extensionForm.onEndConnection();
}
@Override
ExtensionInfo getInfoAnnotations() {
return extInfo;
}
@Override
protected boolean canLeave() {
return extensionForm.canLeave();
}
@Override
protected boolean canDelete() {
return extensionForm.canDelete();
}
};
extensionForm.primaryStage = primaryStage;
Thread t = new Thread(() -> {
extensionForm.extension.run();
//when the extension has ended, close this process
System.exit(0);
});
t.start();
Platform.setImplicitExit(false);
primaryStage.setOnCloseRequest(event -> {
event.consume();
Platform.runLater(() -> {
primaryStage.hide();
extensionForm.onHide();
});
});
}
public static void trigger( Class<? extends ExtensionForm> extension, String[] args) {
ExtensionFormLauncher.extension = extension;
ExtensionFormLauncher.args = args;
launch(args);
}
}

View File

@ -0,0 +1,37 @@
package gearth.misc;
import java.io.PrintStream;
import java.util.prefs.Preferences;
/**
* Created by Jonas on 5/11/2018.
*/
public class AdminValidator {
//https://stackoverflow.com/questions/4350356/detect-if-java-application-was-run-as-a-windows-admin
private static Boolean isAdmin = null;
public static boolean isAdmin() {
if (isAdmin == null) {
Preferences prefs = Preferences.systemRoot();
PrintStream systemErr = System.err;
synchronized(systemErr){ // better synchroize to avoid problems with other threads that access System.err
System.setErr(null);
try{
prefs.put("foo", "bar"); // SecurityException on Windows
prefs.remove("foo");
prefs.flush(); // BackingStoreException on Linux
isAdmin = true;
}catch(Exception e){
isAdmin = false;
}finally{
System.setErr(systemErr);
}
}
}
return isAdmin;
}
}

View File

@ -7,14 +7,17 @@ import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.DialogPane;
import java.util.HashSet;
import java.util.Set;
/**
* Created by Jonas on 27/09/18.
*/
public class ConfirmationDialog {
public static boolean showDialog = true;
private static Set<String> ignoreDialogs = new HashSet<>();
public static Alert createAlertWithOptOut(Alert.AlertType type, String title, String headerText,
public static Alert createAlertWithOptOut(Alert.AlertType type, String dialogKey, String title, String headerText,
String message, String optOutMessage, /*Callback<Boolean, Void> optOutAction,*/
ButtonType... buttonTypes) {
Alert alert = new Alert(type);
@ -29,7 +32,11 @@ public class ConfirmationDialog {
protected Node createDetailsButton() {
CheckBox optOut = new CheckBox();
optOut.setText(optOutMessage);
optOut.setOnAction(event -> showDialog = !optOut.isSelected());
optOut.setOnAction(event -> {
if (optOut.isSelected()) {
ignoreDialogs.add(dialogKey);
}
});
return optOut;
}
});
@ -46,5 +53,8 @@ public class ConfirmationDialog {
return alert;
}
public static boolean showDialog(String dialogKey) {
return !ignoreDialogs.contains(dialogKey);
}
}

View File

@ -111,6 +111,7 @@ public class HConnection {
private volatile boolean autoDetectHost = false;
private volatile String clientHostAndPort = "";
private volatile String hotelVersion = "";
public State getState() {
@ -249,33 +250,33 @@ public class HConnection {
if (DEBUG) System.out.println(habbo_server.getLocalAddress().getHostAddress() + ": " + habbo_server.getLocalPort());
final boolean[] aborted = new boolean[1];
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(this);
OutgoingHandler outgoingHandler = new OutgoingHandler(habbo_server_out, trafficListeners);
rc4Obtainer.setOutgoingHandler(outgoingHandler);
IncomingHandler incomingHandler = new IncomingHandler(client_out, trafficListeners);
rc4Obtainer.setIncomingHandler(incomingHandler);
outgoingHandler.addOnDatastreamConfirmedListener(hotelVersion -> {
this.hotelVersion = hotelVersion;
incomingHandler.setAsDataStream();
clientHostAndPort = client.getLocalAddress().getHostAddress() + ":" + client.getPort();
if (DEBUG) System.out.println(clientHostAndPort);
setState(State.CONNECTED);
onConnect();
outHandler = outgoingHandler;
inHandler = incomingHandler;
});
// wachten op data van client
new Thread(() -> {
try {
OutgoingHandler handler = new OutgoingHandler(habbo_server_out, trafficListeners);
rc4Obtainer.setOutgoingHandler(handler);
while (!client.isClosed() && (state == State.WAITING_FOR_CLIENT || state == State.CONNECTED)) {
byte[] buffer;
while (client_in.available() > 0) {
client_in.read(buffer = new byte[client_in.available()]);
handler.act(buffer);
if (!datastream[0] && handler.isDataStream()) {
clientHostAndPort = client.getLocalAddress().getHostAddress() + ":" + client.getPort();
if (DEBUG) System.out.println(clientHostAndPort);
datastream[0] = true;
setState(State.CONNECTED);
onConnect();
outHandler = handler;
//client_outputStream = client_out;
//server_outputStream = habbo_server_out;
}
outgoingHandler.act(buffer);
}
Thread.sleep(1);
@ -307,18 +308,11 @@ public class HConnection {
// wachten op data van server
new Thread(() -> {
try {
IncomingHandler handler = new IncomingHandler(client_out, trafficListeners);
rc4Obtainer.setIncomingHandler(handler);
while (!habbo_server.isClosed() && (state == State.CONNECTED || state == State.WAITING_FOR_CLIENT)) {
byte[] buffer;
while (habbo_server_in.available() > 0) {
habbo_server_in.read(buffer = new byte[habbo_server_in.available()]);
if (!handler.isDataStream() && datastream[0]) {
handler.setAsDataStream();
inHandler = handler;
}
handler.act(buffer);
incomingHandler.act(buffer);
}
Thread.sleep(1);
}
@ -434,6 +428,7 @@ public class HConnection {
if (state != this.state) {
if (state != State.CONNECTED) {
clientHostAndPort = "";
hotelVersion = "";
}
State buffer = this.state;
@ -510,4 +505,7 @@ public class HConnection {
return clientHostAndPort;
}
public String getHotelVersion() {
return hotelVersion;
}
}

View File

@ -19,6 +19,10 @@ public class HMessage implements StringifyAble {
constructFromString(fromString);
}
public HMessage(HMessage message) {
constructFromHMessage(message);
}
public HMessage(HPacket packet, Side side, int index) {
this.side = side;
this.hPacket = packet;
@ -66,6 +70,13 @@ public class HMessage implements StringifyAble {
this.hPacket = p;
}
public void constructFromHMessage(HMessage message) {
this.isBlocked = message.isBlocked();
this.index = message.getIndex();
this.side = message.getDestination();
this.hPacket = new HPacket(message.getPacket());
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof HMessage)) return false;

View File

@ -17,6 +17,10 @@ public class HPacket implements StringifyAble {
public HPacket(byte[] packet) {
packetInBytes = packet.clone();
}
public HPacket(HPacket packet) {
packetInBytes = packet.packetInBytes.clone();
isEdited = packet.isEdited;
}
public HPacket(String packet) {
packetInBytes = fromStringToBytes(fromExpressionToString(packet));
}
@ -442,20 +446,85 @@ public class HPacket implements StringifyAble {
return this;
}
private boolean canReadString(int index) {
if (index < packetInBytes.length - 1) {
int l = readUshort(index);
if (index + 1 + l < packetInBytes.length) {
return true;
}
}
return false;
}
//returns if done r not
public boolean replaceFirstString(String oldS, String newS) {
public HPacket replaceFirstString(String oldS, String newS) {
return replaceXStrings(oldS, newS, 1);
}
public HPacket replaceXStrings(String oldS, String newS, int amount) {
if (amount == 0) return this;
int i = 6;
while (i < packetInBytes.length - 1 - oldS.length()) {
if (readUshort(i) == oldS.length() && readString(i).equals(oldS)) {
replaceString(i, newS);
return true;
i += 1 + newS.length();
amount -= 1;
if (amount == 0) {
return this;
}
}
i++;
}
return false;
return this;
}
public HPacket replaceAllStrings(String oldS, String newS) {
return replaceXStrings(oldS, newS, -1);
}
public HPacket replaceFirstSubstring(String oldS, String newS) {
return replaceXSubstrings(oldS, newS, 1);
}
public HPacket replaceXSubstrings(String oldS, String newS, int amount) {
if (amount == 0) {
return this;
}
int max = packetInBytes.length;
int i = packetInBytes.length - 2 - oldS.length();
while (i >= 6) {
if (canReadString(i)) {
String s = readString(i);
System.out.println(s.contains(oldS));
if (s.contains(oldS) && i + 2 + s.length() <= max) {
String replacement = s.replaceAll(oldS, newS);
replaceString(i, replacement);
i -= (1 + oldS.length());
amount -= 1;
if (amount == 0) {
return this;
}
max = i;
}
}
i--;
}
return this;
}
public HPacket replaceAllSubstrings(String oldS, String newS) {
return replaceXSubstrings(oldS, newS, -1);
}
public HPacket replaceAllIntegers(int val, int replacement) {
int i = 6;
while (i < packetInBytes.length - 3) {
if (readInteger(i) == val) {
replaceInt(i, replacement);
i += 3;
}
i++;
}
public HPacket replaceAllString(String oldS, String newS) {
while (replaceFirstString(oldS, newS)) {}
return this;
}
@ -547,6 +616,9 @@ public class HPacket implements StringifyAble {
isEdited = remember;
}
public void overrideEditedField(boolean edited) {
isEdited = edited;
}
/**
* returns "" if not found or not sure enough
@ -841,9 +913,6 @@ public class HPacket implements StringifyAble {
}
public static void main(String[] args) {
HPacket packet = new HPacket("{l}{u:1442}");
System.out.println(packet.structureEquals("s,b"));
}
}

View File

@ -4,6 +4,7 @@ import gearth.misc.Cacher;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.memory.habboclient.HabboClient;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
@ -60,7 +61,12 @@ public class WindowsHabboClient extends HabboClient {
}
assert revisionList != null;
List<Object> cachedOffsets = revisionList.getJSONArray(production).toList();
JSONArray cachedOffsets;
if (revisionList.has(production))
cachedOffsets = (JSONArray) revisionList.get(production);
else
cachedOffsets = null;
StringJoiner joiner = new StringJoiner(" ");
if (useCache) {
@ -86,7 +92,7 @@ public class WindowsHabboClient extends HabboClient {
ArrayList<String> possibleData = new ArrayList<>();
if (cachedOffsets == null) {
cachedOffsets = new ArrayList<>();
cachedOffsets = new JSONArray();
}
@ -94,8 +100,8 @@ public class WindowsHabboClient extends HabboClient {
while((line = reader.readLine()) != null) {
if (line.length() > 1) {
if (!useCache && (count++ % 2 == 0)) {
if (!cachedOffsets.contains(line)) {
cachedOffsets.add(line);
if (!cachedOffsets.toList().contains(line)) {
cachedOffsets.put(line);
}
}
else

View File

@ -5,6 +5,8 @@ import gearth.protocol.HPacket;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class OutgoingHandler extends Handler {
@ -12,10 +14,24 @@ public class OutgoingHandler extends Handler {
super(outputStream, listeners);
}
private List<OnDatastreamConfirmedListener> onDatastreamConfirmedListeners = new ArrayList<>();
public void addOnDatastreamConfirmedListener(OnDatastreamConfirmedListener listener) {
onDatastreamConfirmedListeners.add(listener);
}
public interface OnDatastreamConfirmedListener {
void confirm(String hotelVersion);
}
private void dataStreamCheck(byte[] buffer) {
if (!isDataStream) {
HPacket hpacket = new HPacket(buffer);
isDataStream = (hpacket.getBytesLength() > 6 && hpacket.length() < 100);
if (isDataStream) {
String version = hpacket.readString();
for (OnDatastreamConfirmedListener listener : onDatastreamConfirmedListeners) {
listener.confirm(version);
}
}
}
}

View File

@ -1,5 +1,6 @@
package gearth.ui;
import gearth.ui.logger.loggerdisplays.PacketLoggerFactory;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
@ -17,6 +18,7 @@ import gearth.ui.tools.Tools;
public class GEarthController {
public Tab tab_Settings;
public Tab tab_Logger;
public TabPane tabBar;
private Stage stage = null;
private volatile HConnection hConnection;
@ -48,6 +50,10 @@ public class GEarthController {
tabBar.getTabs().remove(tab_Settings);
if (PacketLoggerFactory.usesUIlogger()) {
tabBar.getTabs().remove(tab_Logger);
}
//custom header bar
// final Point[] startpos = {null};

View File

@ -0,0 +1,178 @@
package gearth.ui;
import gearth.protocol.HPacket;
import gearth.ui.logger.loggerdisplays.PacketLogger;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.StyleClassedTextArea;
import org.fxmisc.richtext.model.StyleSpansBuilder;
import java.net.URL;
import java.util.*;
public class UiLoggerController implements Initializable {
public FlowPane flowPane;
public BorderPane borderPane;
public Label lblViewIncoming;
public Label lblViewOutgoing;
public CheckMenuItem chkViewIncoming;
public CheckMenuItem chkViewOutgoing;
public CheckMenuItem chkDisplayStructure;
public Label lblAutoScrolll;
public CheckMenuItem chkAutoscroll;
public CheckMenuItem chkSkipBigPackets;
private StyleClassedTextArea area;
private boolean viewIncoming = true;
private boolean viewOutgoing = true;
private boolean displayStructure = true;
private boolean autoScroll = true;
private boolean skiphugepackets = true;
private volatile boolean initialized = false;
private final List<Element> appendLater = new ArrayList<>();
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
area = new StyleClassedTextArea();
area.getStyleClass().add("dark");
area.setWrapText(true);
VirtualizedScrollPane<StyleClassedTextArea> vsPane = new VirtualizedScrollPane<>(area);
borderPane.setCenter(vsPane);
synchronized (appendLater) {
initialized = true;
if (!appendLater.isEmpty()) {
appendLog(appendLater);
appendLater.clear();
}
}
}
public void appendMessage(HPacket packet, int types) {
boolean isBlocked = (types & PacketLogger.MESSAGE_TYPE.BLOCKED.getValue()) != 0;
boolean isReplaced = (types & PacketLogger.MESSAGE_TYPE.REPLACED.getValue()) != 0;
boolean isIncoming = (types & PacketLogger.MESSAGE_TYPE.INCOMING.getValue()) != 0;
if (isIncoming && !viewIncoming) return;
if (!isIncoming && !viewOutgoing) return;
ArrayList<Element> elements = new ArrayList<>();
String expr = packet.toExpression();
if (isBlocked) elements.add(new Element("[Blocked]\n", "blocked"));
else if (isReplaced) elements.add(new Element("[Replaced]\n", "replaced"));
if (isIncoming) {
// handle skipped eventually
elements.add(new Element("Incoming[", "incoming"));
elements.add(new Element(String.valueOf(packet.headerId()), ""));
elements.add(new Element("]", "incoming"));
elements.add(new Element(" <- ", ""));
if (skiphugepackets && packet.length() > 8000) {
elements.add(new Element("<packet skipped>", "skipped"));
}
else {
elements.add(new Element(packet.toString(), "incoming"));
}
} else {
elements.add(new Element("Outgoing[", "outgoing"));
elements.add(new Element(String.valueOf(packet.headerId()), ""));
elements.add(new Element("]", "outgoing"));
elements.add(new Element(" -> ", ""));
if (skiphugepackets && packet.length() > 8000) {
elements.add(new Element("<packet skipped>", "skipped"));
}
else {
elements.add(new Element(packet.toString(), "outgoing"));
}
}
if (!expr.equals("") && displayStructure && (!skiphugepackets || packet.length() <= 8000))
elements.add(new Element("\n" + expr, "structure"));
elements.add(new Element("\n--------------------\n", ""));
synchronized (appendLater) {
if (initialized) {
appendLog(elements);
}
else {
appendLater.addAll(elements);
}
}
}
private synchronized void appendLog(List<Element> elements) {
Platform.runLater(() -> {
StringBuilder sb = new StringBuilder();
StyleSpansBuilder<Collection<String>> styleSpansBuilder = new StyleSpansBuilder<>(0);
for (Element element : elements) {
sb.append(element.text);
styleSpansBuilder.add(Collections.singleton(element.className), element.text.length());
}
int oldLen = area.getLength();
area.appendText(sb.toString());
// System.out.println(sb.toString());
area.setStyleSpans(oldLen, styleSpansBuilder.create());
if (autoScroll) {
area.moveTo(area.getLength());
area.requestFollowCaret();
}
});
}
public void toggleViewIncoming() {
viewIncoming = !viewIncoming;
lblViewIncoming.setText("View Incoming: " + (viewIncoming ? "True" : "False"));
// chkViewIncoming.setSelected(viewIncoming);
}
public void toggleViewOutgoing() {
viewOutgoing = !viewOutgoing;
lblViewOutgoing.setText("View Outgoing: " + (viewOutgoing ? "True" : "False"));
// chkViewOutgoing.setSelected(viewOutgoing);
}
public void toggleDisplayStructure() {
displayStructure = !displayStructure;
// chkDisplayStructure.setSelected(displayStructure);
}
public void toggleAutoscroll(ActionEvent actionEvent) {
autoScroll = !autoScroll;
lblAutoScrolll.setText("Autoscroll: " + (autoScroll ? "True" : "False"));
}
public void toggleSkipPackets(ActionEvent actionEvent) {
skiphugepackets = !skiphugepackets;
}
}
class Element {
final String text;
final String className;
Element(String text, String className) {
this.text = text;
this.className = className;
}
}

View File

@ -18,8 +18,8 @@ public class BoxButton extends StackPane {
//paths zijn relatief aan deze classpath
public BoxButton(String imageName, String imageOnHoverName) {
this.image = new Image(getClass().getResourceAsStream("files/" + imageName));
this.imageOnHover = new Image(getClass().getResourceAsStream("files/" + imageOnHoverName));
this.image = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/" + imageName));
this.imageOnHover = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/" + imageOnHoverName));
this.imageView = new ImageView();
setCursor(Cursor.DEFAULT);

View File

@ -8,7 +8,6 @@ import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -32,10 +31,10 @@ public class PauseResumeButton extends StackPane{
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 = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonPause.png"));
this.imagePauseOnHover = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonPauseHover.png"));
this.imageResume = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonResume.png"));
this.imageResumeOnHover = new Image(getClass().getResourceAsStream("/gearth/ui/buttons/files/ButtonResumeHover.png"));
this.imageView = new ImageView();
setCursor(Cursor.DEFAULT);

View File

@ -21,6 +21,7 @@ public class Connection extends SubForm {
public TextField outHost;
public TextField outPort;
public CheckBox cbx_autodetect;
public TextField txtfield_hotelversion;
private boolean isBusy = false;
@ -75,6 +76,7 @@ public class Connection extends SubForm {
public void onParentSet(){
getHConnection().addStateChangeListener((oldState, newState) -> Platform.runLater(() -> {
txtfield_hotelversion.setText(getHConnection().getHotelVersion());
if (newState == HConnection.State.NOT_CONNECTED) {
updateInputUI();
lblState.setText("Not connected");

View File

@ -79,10 +79,8 @@ public class ExtensionItemContainer extends GridPane {
Tooltip delete = new Tooltip("Close connection with this extension");
Tooltip.install(exitButton,delete);
exitButton.show();
exitButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.isRemoveClickTrigger());
clickButton = new SimpleClickButton();
clickButton.show();
clickButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.isClickTrigger());
buttonsBox = new HBox(clickButton, exitButton);
@ -101,12 +99,14 @@ public class ExtensionItemContainer extends GridPane {
Tooltip.install(deleteButton, uninstall);
deleteButton.show();
GridPane this2 = this;
final String uninstallKey = "uninstallExtension";
deleteButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
boolean delet_dis = true;
if (ConfirmationDialog.showDialog) {
Alert alert = ConfirmationDialog.createAlertWithOptOut(Alert.AlertType.CONFIRMATION,
"Confirmation Dialog", null,
if (ConfirmationDialog.showDialog(uninstallKey)) {
Alert alert = ConfirmationDialog.createAlertWithOptOut(Alert.AlertType.CONFIRMATION, uninstallKey
,"Confirmation Dialog", null,
"Are you sure want to uninstall this extension?", "Do not ask again",
ButtonType.YES, ButtonType.NO
);

View File

@ -148,15 +148,19 @@ public class Extensions extends SubForm {
getHConnection().addStateChangeListener((oldState, newState) -> {
if (newState == HConnection.State.CONNECTED) {
synchronized (gEarthExtensions) {
for (GEarthExtension extension : gEarthExtensions) {
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONSTART));
}
}
}
if (oldState == HConnection.State.CONNECTED) {
synchronized (getHConnection()) {
for (GEarthExtension extension : gEarthExtensions) {
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONEND));
}
}
}
});
getHConnection().addTrafficListener(1, message -> {
@ -165,13 +169,14 @@ public class Extensions extends SubForm {
collection = new HashSet<>(gEarthExtensions);
}
String stringified = message.stringify();
HPacket manipulatePacketRequest = new HPacket(OUTGOING_MESSAGES_IDS.PACKETINTERCEPT);
manipulatePacketRequest.appendLongString(stringified);
boolean[] isblock = new boolean[1];
HMessage result = new HMessage(message);
boolean[] isblock = new boolean[1];
synchronized (collection) {
for (GEarthExtension extension : collection) {
GEarthExtension.ReceiveMessageListener respondCallback = new GEarthExtension.ReceiveMessageListener() {
@Override
@ -180,8 +185,9 @@ public class Extensions extends SubForm {
String stringifiedresponse = packet.readLongString(6);
HMessage responseMessage = new HMessage(stringifiedresponse);
if (responseMessage.getDestination() == message.getDestination() && responseMessage.getIndex() == message.getIndex()) {
synchronized (result) {
if (!message.equals(responseMessage)) {
message.constructFromString(stringifiedresponse);
result.constructFromString(stringifiedresponse);
}
if (responseMessage.isBlocked()) {
isblock[0] = true;
@ -194,31 +200,40 @@ public class Extensions extends SubForm {
}
}
}
}
};
extension.addOnReceiveMessageListener(respondCallback);
extension.sendMessage(manipulatePacketRequest);
}
}
//block untill all extensions have responded
List<GEarthExtension> willdelete = new ArrayList<>();
while (!collection.isEmpty()) {
while (true) {
synchronized (collection) {
for (GEarthExtension extension : collection) {
if (collection.isEmpty()) {
break;
}
synchronized (gEarthExtensions) {
for (GEarthExtension extension : collection) {
if (!gEarthExtensions.contains(extension)) willdelete.add(extension);
}
}
for (int i = willdelete.size() - 1; i >= 0; i--) {
collection.remove(willdelete.get(i));
willdelete.remove(i);
}
}
try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
}
message.constructFromHMessage(result);
if (isblock[0]) {
message.setBlocked(true);
}
@ -259,14 +274,16 @@ public class Extensions extends SubForm {
}
}
};
synchronized (messageListeners) {
messageListeners.put(extension, receiveMessageListener);
}
extension.addOnReceiveMessageListener(receiveMessageListener);
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.INIT));
if (getHConnection().getState() == HConnection.State.CONNECTED) {
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONSTART));
}
Platform.runLater(() -> producer.extensionConnected(extension));
extension.onRemoveClick(observable -> {
try {
extension.getConnection().close();
@ -275,6 +292,8 @@ public class Extensions extends SubForm {
}
});
extension.onClick(observable -> extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.ONDOUBLECLICK)));
Platform.runLater(() -> producer.extensionConnected(extension));
}
@Override
@ -283,8 +302,10 @@ public class Extensions extends SubForm {
gEarthExtensions.remove(extension);
}
synchronized (messageListeners) {
extension.removeOnReceiveMessageListener(messageListeners.get(extension));
messageListeners.remove(extension);
}
Platform.runLater(extension::delete);
}
});

View File

@ -6,6 +6,7 @@ import gearth.protocol.HPacket;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import gearth.ui.extensions.authentication.Authenticator;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
@ -26,6 +27,7 @@ public class GEarthExtension {
private boolean isInstalledExtension; // <- extension is in the extensions directory
private String fileName;
private String cookie;
private Socket connection;
@ -60,7 +62,14 @@ public class GEarthExtension {
connection,
onDisconnectedCallback
);
if (Authenticator.evaluate(gEarthExtension)) {
callback.act(gEarthExtension);
}
else {
gEarthExtension.closeConnection(); //you shall not pass...
}
break;
}
}
@ -79,6 +88,7 @@ public class GEarthExtension {
this.isInstalledExtension = extensionInfo.readBoolean();
this.fileName = extensionInfo.readString();
this.cookie = extensionInfo.readString();
this.leaveButtonVisible = extensionInfo.readBoolean();
this.deleteButtonVisible = extensionInfo.readBoolean();
@ -103,10 +113,12 @@ public class GEarthExtension {
HPacket packet = new HPacket(headerandbody);
packet.fixLength();
synchronized (receiveMessageListeners) {
for (int i = receiveMessageListeners.size() - 1; i >= 0; i--) {
receiveMessageListeners.get(i).act(packet);
packet.setReadIndex(6);
}
}
}
@ -149,6 +161,9 @@ public class GEarthExtension {
public String getFileName() {
return fileName;
}
public String getCookie() {
return cookie;
}
public boolean isDeleteButtonVisible() {
return deleteButtonVisible;
}
@ -181,13 +196,17 @@ public class GEarthExtension {
}
private List<ReceiveMessageListener> receiveMessageListeners = new ArrayList<>();
private final List<ReceiveMessageListener> receiveMessageListeners = new ArrayList<>();
public void addOnReceiveMessageListener(ReceiveMessageListener receiveMessageListener) {
synchronized (receiveMessageListeners) {
receiveMessageListeners.add(receiveMessageListener);
}
}
public void removeOnReceiveMessageListener(ReceiveMessageListener receiveMessageListener) {
synchronized (receiveMessageListeners) {
receiveMessageListeners.remove(receiveMessageListener);
}
}
public interface ReceiveMessageListener {
void act(HPacket message);
@ -200,33 +219,45 @@ public class GEarthExtension {
}
private List<InvalidationListener> onRemoveClickListener = new ArrayList<>();
private final List<InvalidationListener> onRemoveClickListener = new ArrayList<>();
public void onRemoveClick(InvalidationListener listener) {
synchronized (onRemoveClickListener) {
onRemoveClickListener.add(listener);
}
}
public void isRemoveClickTrigger() {
synchronized (onRemoveClickListener) {
for (int i = onRemoveClickListener.size() - 1; i >= 0; i--) {
onRemoveClickListener.get(i).invalidated(null);
}
}
}
private List<InvalidationListener> onClickListener = new ArrayList<>();
private final List<InvalidationListener> onClickListener = new ArrayList<>();
public void onClick(InvalidationListener listener) {
synchronized (onClickListener) {
onClickListener.add(listener);
}
}
public void isClickTrigger() {
synchronized (onClickListener) {
for (int i = onClickListener.size() - 1; i >= 0; i--) {
onClickListener.get(i).invalidated(null);
}
}
}
private List<InvalidationListener> onDeleteListeners = new ArrayList<>();
private final List<InvalidationListener> onDeleteListeners = new ArrayList<>();
public void onDelete(InvalidationListener listener) {
synchronized (onDeleteListeners) {
onDeleteListeners.add(listener);
}
}
public void delete() {
synchronized (onDeleteListeners) {
for (int i = onDeleteListeners.size() - 1; i >= 0; i--) {
onDeleteListeners.get(i).invalidated(null);
}
}
}
}

View File

@ -0,0 +1,101 @@
package gearth.ui.extensions.authentication;
import gearth.extensions.Extension;
import gearth.misc.ConfirmationDialog;
import gearth.ui.extensions.GEarthExtension;
import gearth.ui.extensions.executer.ExtensionRunner;
import gearth.ui.extensions.executer.ExtensionRunnerFactory;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* Created by Jonas on 16/10/18.
*/
public class Authenticator {
private static Map<String, String> cookies = new HashMap<>();
public static String generateCookieForExtension(String filename) {
String cookie = getRandomCookie();
cookies.put(filename, cookie);
return cookie;
}
public static boolean evaluate(GEarthExtension extension) {
if (extension.isInstalledExtension()) {
return claimSession(extension.getFileName(), extension.getCookie());
}
else {
return askForPermission(extension);
}
}
/**
* authenticator: authenticate an extension and remove the cookie
* @param filename
* @param cookie
* @return if the extension is authenticated
*/
private static boolean claimSession(String filename, String cookie) {
if (cookies.containsKey(filename) && cookies.get(filename).equals(cookie)) {
cookies.remove(filename);
return true;
}
return false;
}
private static volatile boolean rememberOption = false;
//for not-installed extensions, popup a dialog
private static boolean askForPermission(GEarthExtension extension) {
boolean[] allowConnection = {true};
final String connectExtensionKey = "allow_extension_connection";
if (ConfirmationDialog.showDialog(connectExtensionKey)) {
boolean[] done = {false};
Platform.runLater(() -> {
Alert alert = ConfirmationDialog.createAlertWithOptOut(Alert.AlertType.WARNING, connectExtensionKey
,"Confirmation Dialog", null,
"Extension \""+extension.getTitle()+"\" tries to connect but isn't known to G-Earth, accept this connection?", "Remember my choice",
ButtonType.YES, ButtonType.NO
);
if (!(alert.showAndWait().filter(t -> t == ButtonType.YES).isPresent())) {
allowConnection[0] = false;
}
done[0] = true;
if (!ConfirmationDialog.showDialog(connectExtensionKey)) {
rememberOption = allowConnection[0];
}
});
while (!done[0]) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return allowConnection[0];
}
return rememberOption;
}
private static String getRandomCookie() {
StringBuilder builder = new StringBuilder();
Random r = new Random();
for (int i = 0; i < 40; i++) {
builder.append(r.nextInt(40));
}
return builder.toString();
}
}

View File

@ -25,7 +25,7 @@ public class ExecutionInfo {
for(String type : extensionTypeToExecutionCommand.keySet()) {
extensionTypeToExecutionCommand.put(
type,
extensionTypeToExecutionCommand.get(type) + " -p {port} -f {filename}"
extensionTypeToExecutionCommand.get(type) + " -p {port} -f {filename} -c {cookie}"
);
}

View File

@ -1,6 +1,7 @@
package gearth.ui.extensions.executer;
import gearth.Main;
import gearth.ui.extensions.authentication.Authenticator;
import java.io.File;
import java.io.IOException;
@ -70,11 +71,13 @@ public class NormalExtensionRunner implements ExtensionRunner {
public void tryRunExtension(String path, int port) {
try {
String filename = Paths.get(path).getFileName().toString();
Runtime.getRuntime().exec(
ExecutionInfo.getExecutionCommand(getFileExtension(path))
.replace("{path}", path)
.replace("{port}", port+"")
.replace("{filename}", Paths.get(path).getFileName().toString())
.replace("{filename}", filename)
.replace("{cookie}", Authenticator.generateCookieForExtension(filename))
);
} catch (IOException e) {
e.printStackTrace();
@ -119,7 +122,7 @@ public class NormalExtensionRunner implements ExtensionRunner {
private String getRandomString() {
StringBuilder builder = new StringBuilder();
Random r = new Random();
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 12; i++) {
builder.append(r.nextInt(10));
}

View File

@ -0,0 +1,73 @@
package gearth.ui.info;
import gearth.Main;
import javafx.event.ActionEvent;
import javafx.scene.control.Hyperlink;
import gearth.ui.SubForm;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
/**
* Created by Jonas on 06/04/18.
*/
public class Info extends SubForm {
public ImageView img_logo;
public Hyperlink link_sng;
public Hyperlink link_darkbox;
public Hyperlink link_d_harble;
public Hyperlink link_g_gearth;
public Hyperlink link_g_tanji;
public Hyperlink link_d_bonnie;
public Label version;
// this is a TEMPORARY info tab
private void activateHyperlink(Hyperlink link) {
link.setOnAction((ActionEvent event) -> {
Hyperlink h = (Hyperlink) event.getTarget();
String s = h.getTooltip().getText();
Main.main.getHostServices().showDocument(s);
event.consume();
});
}
public void initialize() {
version.setText(version.getText().replace("$version", Main.version));
img_logo.setImage(new Image("/gearth/G-EarthLogo.png"));
link_sng.setTooltip(new Tooltip("https://www.sngforum.info"));
link_darkbox.setTooltip(new Tooltip("https://darkbox.nl"));
link_g_gearth.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth"));
link_g_tanji.setTooltip(new Tooltip("https://github.com/ArachisH/Tanji"));
link_d_harble.setTooltip(new Tooltip("https://discord.gg/Vyc2gFC"));
link_d_bonnie.setTooltip(new Tooltip("https://discord.gg/KZa3rXD"));
activateHyperlink(link_d_harble);
activateHyperlink(link_d_bonnie);
activateHyperlink(link_g_gearth);
activateHyperlink(link_g_tanji);
activateHyperlink(link_sng);
activateHyperlink(link_darkbox);
// String[] lines = {
// "G-Earth 0.1.1",
// "Linux Habbo Packet Manipulator",
// "",
// "Made by:",
// "sirjonasxx",
// "",
// "Contributors:",
// "XePeleato (Windows & Mac support)",
// "Scott Stamp",
// "LittleJ",
// "ArachisH",
// "",
// "Check out:",
// "sngforum.info",
// "darkbox.nl"
// };
}
}

View File

@ -1,5 +1,6 @@
package gearth.ui.logger;
import gearth.ui.logger.loggerdisplays.UiLogger;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;

View File

@ -1,5 +1,6 @@
package gearth.ui.logger.loggerdisplays;
import gearth.Main;
import gearth.misc.OSValidator;
/**
@ -7,13 +8,18 @@ import gearth.misc.OSValidator;
*/
public class PacketLoggerFactory {
public static boolean usesUIlogger() {
return (!Main.hasFlag("-t"));
}
public static PacketLogger get() {
if (usesUIlogger()) {
return new UiLogger();
}
if (OSValidator.isUnix()) {
return new LinuxTerminalLogger();
}
// if (System.getenv("XDG_CURRENT_DESKTOP") != null && System.getenv("XDG_CURRENT_DESKTOP").toLowerCase().contains("gnome")) {
// return new GnomeTerminalLogger();
// }
return new SimpleTerminalLogger();
}

View File

@ -0,0 +1,111 @@
package gearth.ui.logger.loggerdisplays;
import gearth.protocol.HPacket;
import gearth.ui.UiLoggerController;
import javafx.event.Event;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class UiLogger implements PacketLogger {
private Stage stage;
private UiLoggerController controller = null;
@Override
public void start() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/gearth/ui/logger/uilogger/UiLogger.fxml"));
try {
Parent root = loader.load();
synchronized (appendLater) {
controller = loader.getController();
for (Elem elem : appendLater) {
controller.appendMessage(elem.packet, elem.types);
}
appendLater.clear();
}
stage = new Stage();
stage.setTitle("G-Earth | Packet Logger");
stage.initModality(Modality.NONE);
Scene scene = new Scene(root);
scene.getStylesheets().add("/gearth/ui/bootstrap3.css");
scene.getStylesheets().add("/gearth/ui/logger/uilogger/logger.css");
// scene.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
// final KeyCombination keyCombIncoming = new KeyCodeCombination(KeyCode.I,
// KeyCombination.CONTROL_DOWN);
// final KeyCombination keyCombOutgoing = new KeyCodeCombination(KeyCode.O,
// KeyCombination.CONTROL_DOWN);
//
// public void handle(KeyEvent ke) {
// if (keyCombIncoming.match(ke)) {
// controller.toggleViewIncoming();
// ke.consume();
// } else if (keyCombOutgoing.match(ke)) {
// controller.toggleViewOutgoing();
// ke.consume();
// }
// }
// });
stage.setScene(scene);
// ScenicView.show(scene);
// don't let the user close this window on their own
stage.setOnCloseRequest(Event::consume);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void stop() {
if (stage != null)
stage.close();
}
@Override
public void appendSplitLine() {
// don't use this, we can't discern incoming/outgoing
//Platform.runLater(() -> controller.appendSplitLine());
}
private class Elem {
HPacket packet;
int types;
Elem(HPacket packet, int types) {
this.packet = packet;
this.types = types;
}
}
private final List<Elem> appendLater = new ArrayList<>();
@Override
public void appendMessage(HPacket packet, int types) {
synchronized (appendLater) {
if (controller == null) {
appendLater.add(new Elem(packet, types));
}
else {
controller.appendMessage(packet, types);
}
}
}
@Override
public void appendStructure(HPacket packet) {
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<!--maxHeight="19.0" minHeight="19.0"-->
<VBox xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="gearth.ui.GEarthController">
<Pane fx:id="mover" maxHeight="0.0" minHeight="0.0" prefWidth="200.0"/>
<TabPane fx:id="tabBar" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="295.0" prefWidth="565.0" tabClosingPolicy="UNAVAILABLE">
<Tab text="Connection">
<fx:include fx:id="connection" source="connection/Connection.fxml"/>
</Tab>
<Tab fx:id="tab_Logger" text="Logger">
<fx:include fx:id="logger" source="logger/Logger.fxml"/>
</Tab>
<Tab text="Injection">
<fx:include fx:id="injection" source="injection/Injection.fxml"/>
</Tab>
<Tab text="Tools">
<fx:include fx:id="tools" source="tools/Tools.fxml"/>
</Tab>
<Tab text="Scheduler">
<fx:include fx:id="scheduler" source="scheduler/Scheduler.fxml"/>
</Tab>
<Tab fx:id="tab_Settings" text="Settings">
<fx:include fx:id="settings" source="settings/Settings.fxml"/>
</Tab>
<Tab text="Extensions">
<fx:include fx:id="extensions" source="extensions/Extensions.fxml"/>
</Tab>
<Tab text="Info">
<fx:include fx:id="info" source="info/Info.fxml"/>
</Tab>
</TabPane>
</VBox>

View File

@ -152,7 +152,7 @@ VBox > .split-menu-button.last > .arrow-button {
.font-menu-button,
.split-menu-button > .label,.split-menu-button > .arrow-button {
-fx-border-color: #cccccc;
-fx-text-fill: #333333;
-fx-text-fill: #000000;
}
/*just for the special split menu button*/
.split-menu-button > .label {
@ -342,7 +342,7 @@ VBox > .split-menu-button.last > .arrow-button {
}
.menu-item:focused > * {
-fx-text-fill: #262626;
-fx-text-fill: #000000;
}
.menu-item:focused .arrow {
-fx-background-color: #333333;

Some files were not shown because too many files have changed in this diff Show More