diff --git a/.gitignore b/.gitignore
index 5435a47..8f231aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,4 @@
out/
bin/
**/target/
-*.iml
+*.iml
\ No newline at end of file
diff --git a/Extensions/AdminOnConnect/pom.xml b/Extensions/AdminOnConnect/pom.xml
index 7a5eab6..2706564 100644
--- a/Extensions/AdminOnConnect/pom.xml
+++ b/Extensions/AdminOnConnect/pom.xml
@@ -13,7 +13,7 @@
G-Earth
G-Earth-Parent
- 0.0.1-beta
+ 0.2
@@ -30,53 +30,6 @@
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.7.0
-
-
- 1.8
-
-
-
-
- maven-resources-plugin
- 2.6
-
-
- copy-resources
- validate
-
- copy-resources
-
-
- ${project.build.directory}
-
-
- src/main/resources
-
-
-
-
-
-
-
-
- maven-dependency-plugin
-
-
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/bin/lib
-
-
-
-
-
org.apache.maven.plugins
maven-jar-plugin
@@ -93,7 +46,34 @@
true
- ${artifactId}
+ ${project.artifactId}
+
+
+
+
+
+ maven-assembly-plugin
+ 2.5
+
+
+ package
+
+ single
+
+
+
+
+ ${project.build.directory}/bin
+
+
+ extensions.adminonconnect.AdminOnConnect
+
+
+
+ jar-with-dependencies
+
+ ${project.artifactId}
+ false
@@ -102,8 +82,8 @@
G-Earth
- G-Earth-UI
- 0.0.1-beta
+ G-Earth
+ 0.2
diff --git a/Extensions/BlockReplacePackets/pom.xml b/Extensions/BlockReplacePackets/pom.xml
index 1eb4c34..bc0b31a 100644
--- a/Extensions/BlockReplacePackets/pom.xml
+++ b/Extensions/BlockReplacePackets/pom.xml
@@ -13,7 +13,7 @@
G-Earth
G-Earth-Parent
- 0.0.1-beta
+ 0.2
@@ -30,53 +30,6 @@
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.7.0
-
-
- 1.8
-
-
-
-
- maven-resources-plugin
- 2.6
-
-
- copy-resources
- validate
-
- copy-resources
-
-
- ${project.build.directory}
-
-
- src/main/resources
-
-
-
-
-
-
-
-
- maven-dependency-plugin
-
-
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/bin/lib
-
-
-
-
-
org.apache.maven.plugins
maven-jar-plugin
@@ -93,12 +46,13 @@
true
- ${artifactId}
+ ${project.artifactId}
maven-assembly-plugin
+ 2.5
package
@@ -108,7 +62,7 @@
- ${project.parent.basedir}/bin
+ ${project.build.directory}/bin
extensions.blockreplacepackets.BlockAndReplacePackets
@@ -117,7 +71,7 @@
jar-with-dependencies
- BlockAndReplacePackets
+ ${project.artifactId}
false
@@ -127,8 +81,8 @@
G-Earth
- G-Earth-UI
- 0.0.1-beta
+ G-Earth
+ 0.2
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java
index fb0361e..1eda9b0 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java
@@ -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 cmb_type;
- public TextField txt_id;
public Button btn_add;
+ public volatile ComboBox cmb_side;
+ public TextField txt_value;
+ public ScrollPane scrollpane;
+ public VBox vbox;
+ public GridPane header;
+
+ List 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;
}
}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/RuleContainer.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/RuleContainer.java
new file mode 100644
index 0000000..9826502
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/RuleContainer.java
@@ -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;
+ }
+
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/blockreplace.fxml b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/blockreplace.fxml
index 893f2a8..fb7940c 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/blockreplace.fxml
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/blockreplace.fxml
@@ -4,73 +4,144 @@
-
-
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+
-
+
-
-
-
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockPacketRule.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockPacketRule.java
new file mode 100644
index 0000000..3083cbb
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockPacketRule.java
@@ -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 "/";
+ }
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockReplaceRule.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockReplaceRule.java
new file mode 100644
index 0000000..d1cc521
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockReplaceRule.java
@@ -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 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);
+ }
+ }
+
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceIntegerRule.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
new file mode 100644
index 0000000..fd06854
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
@@ -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+"";
+ }
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplacePacketRule.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplacePacketRule.java
new file mode 100644
index 0000000..bd49b13
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplacePacketRule.java
@@ -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();
+ }
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceStringRule.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceStringRule.java
new file mode 100644
index 0000000..c783e88
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceStringRule.java
@@ -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;
+ }
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceSubstringRule.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
new file mode 100644
index 0000000..f2ed9e6
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
@@ -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;
+ }
+}
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/RuleFactory.java b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/RuleFactory.java
new file mode 100644
index 0000000..051bc28
--- /dev/null
+++ b/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/RuleFactory.java
@@ -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;
+ }
+
+}
diff --git a/Extensions/SpeechColorizer/pom.xml b/Extensions/SpeechColorizer/pom.xml
index 54ae551..405e87c 100644
--- a/Extensions/SpeechColorizer/pom.xml
+++ b/Extensions/SpeechColorizer/pom.xml
@@ -13,7 +13,7 @@
G-Earth
G-Earth-Parent
- 0.0.1-beta
+ 0.2
@@ -30,53 +30,6 @@
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.7.0
-
-
- 1.8
-
-
-
-
- maven-resources-plugin
- 2.6
-
-
- copy-resources
- validate
-
- copy-resources
-
-
- ${project.build.directory}
-
-
- src/main/resources
-
-
-
-
-
-
-
-
- maven-dependency-plugin
-
-
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/bin/lib
-
-
-
-
-
org.apache.maven.plugins
maven-jar-plugin
@@ -93,12 +46,13 @@
true
- ${artifactId}
+ ${project.artifactId}
maven-assembly-plugin
+ 2.5
package
@@ -108,7 +62,7 @@
- ${project.parent.basedir}/target/bin
+ ${project.build.directory}/bin
extensions.speechcolorizer.SpeechColorizer
@@ -117,6 +71,8 @@
jar-with-dependencies
+ ${project.artifactId}
+ false
@@ -125,8 +81,8 @@
G-Earth
- G-Earth-UI
- 0.0.1-beta
+ G-Earth
+ 0.2
diff --git a/Extensions/SpeechColorizer/src/main/java/extensions/speechcolorizer/SpeechColorizer.java b/Extensions/SpeechColorizer/src/main/java/extensions/speechcolorizer/SpeechColorizer.java
index f01feb7..ce9f769 100644
--- a/Extensions/SpeechColorizer/src/main/java/extensions/speechcolorizer/SpeechColorizer.java
+++ b/Extensions/SpeechColorizer/src/main/java/extensions/speechcolorizer/SpeechColorizer.java
@@ -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(
diff --git a/G-Earth-UI/src/main/java/gearth/Main.java b/G-Earth-UI/src/main/java/gearth/Main.java
deleted file mode 100644
index 06c87c7..0000000
--- a/G-Earth-UI/src/main/java/gearth/Main.java
+++ /dev/null
@@ -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);
- }
-}
diff --git a/G-Earth-UI/src/main/java/gearth/extensions/ExtensionForm.java b/G-Earth-UI/src/main/java/gearth/extensions/ExtensionForm.java
deleted file mode 100644
index 75d04fd..0000000
--- a/G-Earth-UI/src/main/java/gearth/extensions/ExtensionForm.java
+++ /dev/null
@@ -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(){}
-}
diff --git a/G-Earth-UI/src/main/java/gearth/ui/G-Earth.fxml b/G-Earth-UI/src/main/java/gearth/ui/G-Earth.fxml
deleted file mode 100644
index 0541f2f..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/G-Earth.fxml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/connection/Connection.fxml b/G-Earth-UI/src/main/java/gearth/ui/connection/Connection.fxml
deleted file mode 100644
index 8c15eb6..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/connection/Connection.fxml
+++ /dev/null
@@ -1,207 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/extensions/Extensions.fxml b/G-Earth-UI/src/main/java/gearth/ui/extensions/Extensions.fxml
deleted file mode 100644
index 6cba7b5..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/extensions/Extensions.fxml
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/info/Info.fxml b/G-Earth-UI/src/main/java/gearth/ui/info/Info.fxml
deleted file mode 100644
index 9d38147..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/info/Info.fxml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/info/Info.java b/G-Earth-UI/src/main/java/gearth/ui/info/Info.java
deleted file mode 100644
index c3f491f..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/info/Info.java
+++ /dev/null
@@ -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
- );
- }
-}
diff --git a/G-Earth-UI/src/main/java/gearth/ui/injection/Injection.fxml b/G-Earth-UI/src/main/java/gearth/ui/injection/Injection.fxml
deleted file mode 100644
index 42bfd50..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/injection/Injection.fxml
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/logger/Logger.fxml b/G-Earth-UI/src/main/java/gearth/ui/logger/Logger.fxml
deleted file mode 100644
index d903d11..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/logger/Logger.fxml
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/scheduler/Scheduler.fxml b/G-Earth-UI/src/main/java/gearth/ui/scheduler/Scheduler.fxml
deleted file mode 100644
index 447e01c..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/scheduler/Scheduler.fxml
+++ /dev/null
@@ -1,141 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/src/main/java/gearth/ui/tools/Tools.fxml b/G-Earth-UI/src/main/java/gearth/ui/tools/Tools.fxml
deleted file mode 100644
index 98848fa..0000000
--- a/G-Earth-UI/src/main/java/gearth/ui/tools/Tools.fxml
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/G-Earth-UI/pom.xml b/G-Earth/pom.xml
similarity index 51%
rename from G-Earth-UI/pom.xml
rename to G-Earth/pom.xml
index 2643b90..23961fe 100644
--- a/G-Earth-UI/pom.xml
+++ b/G-Earth/pom.xml
@@ -4,80 +4,21 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- G-Earth-UI
+ G-Earth
jar
- 0.0.1-beta
+ 0.2
G-Earth
G-Earth-Parent
- 0.0.1-beta
+ 0.2
-
-
-
- false
- src/main/java
-
- **/*.fxml
- **/*.css
- **/*.png
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.7.0
-
-
- 1.8
-
-
-
-
- maven-dependency-plugin
-
-
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/bin/lib
-
-
-
-
-
-
- maven-resources-plugin
- 2.6
-
-
- copy-resources
- validate
-
- copy-resources
-
-
- ${project.build.directory}
-
-
- src/main/resources
-
-
-
-
-
-
@@ -100,6 +41,7 @@
maven-assembly-plugin
+ 2.5
package
@@ -109,7 +51,7 @@
- ${project.parent.basedir}/bin
+ ${project.build.directory}/bin
gearth.Main
@@ -136,5 +78,10 @@
richtextfx
0.9.1
+
+ org.jsoup
+ jsoup
+ 1.11.2
+
\ No newline at end of file
diff --git a/G-Earth-UI/src/META-INF/MANIFEST.MF b/G-Earth/src/META-INF/MANIFEST.MF
similarity index 100%
rename from G-Earth-UI/src/META-INF/MANIFEST.MF
rename to G-Earth/src/META-INF/MANIFEST.MF
diff --git a/G-Earth/src/main/java/gearth/Main.java b/G-Earth/src/main/java/gearth/Main.java
new file mode 100644
index 0000000..6e2f28e
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/Main.java
@@ -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("A new version of G-Earth has been found ("+gitv+")
Update to the latest version:
https://github.com/sirjonasxx/G-Earth/releases");
+ 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;
+ }
+}
diff --git a/G-Earth-UI/src/main/java/gearth/extensions/Extension.java b/G-Earth/src/main/java/gearth/extensions/Extension.java
similarity index 93%
rename from G-Earth-UI/src/main/java/gearth/extensions/Extension.java
rename to G-Earth/src/main/java/gearth/extensions/Extension.java
index b4dc3e0..f720a01 100644
--- a/G-Earth-UI/src/main/java/gearth/extensions/Extension.java
+++ b/G-Earth/src/main/java/gearth/extensions/Extension.java
@@ -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> 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);
diff --git a/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java b/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java
new file mode 100644
index 0000000..e24a816
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java
@@ -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;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java b/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java
new file mode 100644
index 0000000..b0c7253
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java
@@ -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);
+ }
+
+}
diff --git a/G-Earth-UI/src/main/java/gearth/extensions/ExtensionInfo.java b/G-Earth/src/main/java/gearth/extensions/ExtensionInfo.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/extensions/ExtensionInfo.java
rename to G-Earth/src/main/java/gearth/extensions/ExtensionInfo.java
diff --git a/G-Earth-UI/src/main/java/gearth/extensions/extra/Inspector.java b/G-Earth/src/main/java/gearth/extensions/extra/Inspector.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/extensions/extra/Inspector.java
rename to G-Earth/src/main/java/gearth/extensions/extra/Inspector.java
diff --git a/G-Earth/src/main/java/gearth/misc/AdminValidator.java b/G-Earth/src/main/java/gearth/misc/AdminValidator.java
new file mode 100644
index 0000000..ca31aab
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/misc/AdminValidator.java
@@ -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;
+ }
+
+}
diff --git a/G-Earth-UI/src/main/java/gearth/misc/Cacher.java b/G-Earth/src/main/java/gearth/misc/Cacher.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/misc/Cacher.java
rename to G-Earth/src/main/java/gearth/misc/Cacher.java
diff --git a/G-Earth-UI/src/main/java/gearth/misc/ConfirmationDialog.java b/G-Earth/src/main/java/gearth/misc/ConfirmationDialog.java
similarity index 79%
rename from G-Earth-UI/src/main/java/gearth/misc/ConfirmationDialog.java
rename to G-Earth/src/main/java/gearth/misc/ConfirmationDialog.java
index 3f9e7c6..1287a4b 100644
--- a/G-Earth-UI/src/main/java/gearth/misc/ConfirmationDialog.java
+++ b/G-Earth/src/main/java/gearth/misc/ConfirmationDialog.java
@@ -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 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 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);
+ }
}
diff --git a/G-Earth-UI/src/main/java/gearth/misc/OSValidator.java b/G-Earth/src/main/java/gearth/misc/OSValidator.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/misc/OSValidator.java
rename to G-Earth/src/main/java/gearth/misc/OSValidator.java
diff --git a/G-Earth-UI/src/main/java/gearth/misc/StringifyAble.java b/G-Earth/src/main/java/gearth/misc/StringifyAble.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/misc/StringifyAble.java
rename to G-Earth/src/main/java/gearth/misc/StringifyAble.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/HConnection.java b/G-Earth/src/main/java/gearth/protocol/HConnection.java
similarity index 93%
rename from G-Earth-UI/src/main/java/gearth/protocol/HConnection.java
rename to G-Earth/src/main/java/gearth/protocol/HConnection.java
index a3c9763..9c93d08 100644
--- a/G-Earth-UI/src/main/java/gearth/protocol/HConnection.java
+++ b/G-Earth/src/main/java/gearth/protocol/HConnection.java
@@ -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;
+ }
}
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/HMessage.java b/G-Earth/src/main/java/gearth/protocol/HMessage.java
similarity index 87%
rename from G-Earth-UI/src/main/java/gearth/protocol/HMessage.java
rename to G-Earth/src/main/java/gearth/protocol/HMessage.java
index a64a8d1..dbf1406 100644
--- a/G-Earth-UI/src/main/java/gearth/protocol/HMessage.java
+++ b/G-Earth/src/main/java/gearth/protocol/HMessage.java
@@ -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;
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/HPacket.java b/G-Earth/src/main/java/gearth/protocol/HPacket.java
similarity index 92%
rename from G-Earth-UI/src/main/java/gearth/protocol/HPacket.java
rename to G-Earth/src/main/java/gearth/protocol/HPacket.java
index f87dc87..f7a8ed7 100644
--- a/G-Earth-UI/src/main/java/gearth/protocol/HPacket.java
+++ b/G-Earth/src/main/java/gearth/protocol/HPacket.java
@@ -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 replaceAllString(String oldS, String newS) {
- while (replaceFirstString(oldS, newS)) {}
+ 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++;
+ }
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"));
}
}
\ No newline at end of file
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/StateChangeListener.java b/G-Earth/src/main/java/gearth/protocol/StateChangeListener.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/StateChangeListener.java
rename to G-Earth/src/main/java/gearth/protocol/StateChangeListener.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/TrafficListener.java b/G-Earth/src/main/java/gearth/protocol/TrafficListener.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/TrafficListener.java
rename to G-Earth/src/main/java/gearth/protocol/TrafficListener.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/crypto/RC4.java b/G-Earth/src/main/java/gearth/protocol/crypto/RC4.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/crypto/RC4.java
rename to G-Earth/src/main/java/gearth/protocol/crypto/RC4.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/HostReplacer.java b/G-Earth/src/main/java/gearth/protocol/hostreplacer/HostReplacer.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/HostReplacer.java
rename to G-Earth/src/main/java/gearth/protocol/hostreplacer/HostReplacer.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/HostReplacerFactory.java b/G-Earth/src/main/java/gearth/protocol/hostreplacer/HostReplacerFactory.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/HostReplacerFactory.java
rename to G-Earth/src/main/java/gearth/protocol/hostreplacer/HostReplacerFactory.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/UnixHostReplacer.java b/G-Earth/src/main/java/gearth/protocol/hostreplacer/UnixHostReplacer.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/UnixHostReplacer.java
rename to G-Earth/src/main/java/gearth/protocol/hostreplacer/UnixHostReplacer.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/WindowsHostReplacer.java b/G-Earth/src/main/java/gearth/protocol/hostreplacer/WindowsHostReplacer.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/hostreplacer/WindowsHostReplacer.java
rename to G-Earth/src/main/java/gearth/protocol/hostreplacer/WindowsHostReplacer.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/memory/Rc4Obtainer.java b/G-Earth/src/main/java/gearth/protocol/memory/Rc4Obtainer.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/memory/Rc4Obtainer.java
rename to G-Earth/src/main/java/gearth/protocol/memory/Rc4Obtainer.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/HabboClient.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/HabboClient.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/HabboClient.java
rename to G-Earth/src/main/java/gearth/protocol/memory/habboclient/HabboClient.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/HabboClientFactory.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/HabboClientFactory.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/HabboClientFactory.java
rename to G-Earth/src/main/java/gearth/protocol/memory/habboclient/HabboClientFactory.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxHabboClient.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxHabboClient.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxHabboClient.java
rename to G-Earth/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxHabboClient.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxMemorySnippet.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxMemorySnippet.java
similarity index 100%
rename from G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxMemorySnippet.java
rename to G-Earth/src/main/java/gearth/protocol/memory/habboclient/linux/LinuxMemorySnippet.java
diff --git a/G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
similarity index 92%
rename from G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
rename to G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
index 4bb41bd..dcd4d42 100644
--- a/G-Earth-UI/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
+++ b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
@@ -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