diff --git a/Extensions/AdminOnConnect/pom.xml b/Extensions/AdminOnConnect/pom.xml
index ce4d9c4..7ba81c5 100644
--- a/Extensions/AdminOnConnect/pom.xml
+++ b/Extensions/AdminOnConnect/pom.xml
@@ -13,7 +13,7 @@
G-Earth
G-Earth-Parent
- 1.3.4
+ 1.4
../../
@@ -106,7 +106,7 @@
G-Earth
G-Earth
- 1.3.4
+ 1.4
diff --git a/Extensions/BlockReplacePackets/pom.xml b/Extensions/BlockReplacePackets/pom.xml
deleted file mode 100644
index 9a1a6fc..0000000
--- a/Extensions/BlockReplacePackets/pom.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
- 4.0.0
-
- BlockReplacePackets
-
- jar
-
- 0.0.1-beta
-
-
- G-Earth
- G-Earth-Parent
- 1.3.4
- ../../
-
-
-
-
-
-
- false
- src/main/java
-
- **/*.fxml
- **/*.css
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 2.5
-
- ${project.build.directory}/bin
-
-
- true
- true
- extensions.blockreplacepackets.BlockAndReplacePackets
- false
- lib/
- true
-
-
- ${project.artifactId}
-
-
-
-
- maven-assembly-plugin
- 2.5
-
-
- package
-
- single
-
-
-
-
- ${project.build.directory}/bin
-
-
- extensions.blockreplacepackets.BlockAndReplacePackets
-
-
-
- jar-with-dependencies
-
- ${project.artifactId}
- false
-
-
-
-
-
- maven-antrun-plugin
- 3.0.0
-
-
- package
-
-
-
-
-
-
-
-
-
- run
-
-
-
-
-
-
-
-
-
-
- G-Earth
- G-Earth
- 1.3.4
-
-
-
-
\ No newline at end of file
diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml
index a93eb89..5824e8b 100644
--- a/G-Earth/pom.xml
+++ b/G-Earth/pom.xml
@@ -8,7 +8,7 @@
jar
- 1.3.4
+ 1.4
1.8
@@ -18,7 +18,7 @@
G-Earth
G-Earth-Parent
- 1.3.4
+ 1.4
diff --git a/G-Earth/src/main/java/gearth/Main.java b/G-Earth/src/main/java/gearth/Main.java
index 1fa04e6..7e4d733 100644
--- a/G-Earth/src/main/java/gearth/Main.java
+++ b/G-Earth/src/main/java/gearth/Main.java
@@ -28,7 +28,7 @@ import java.util.Set;
public class Main extends Application {
public static Application main;
- public static String version = "1.3.4";
+ public static String version = "1.4";
private static String gitApi = "https://api.github.com/repos/sirjonasxx/G-Earth/releases/latest";
@Override
@@ -45,7 +45,7 @@ public class Main extends Application {
primaryStage.setResizable(false);
primaryStage.setTitle("G-Earth " + version);
- primaryStage.setScene(new Scene(root, 650, 295));
+ primaryStage.setScene(new Scene(root, 650, 290));
primaryStage.show();
primaryStage.getScene().getStylesheets().add(getClass().getResource("ui/bootstrap3.css").toExternalForm());
diff --git a/G-Earth/src/main/java/gearth/extensions/Extension.java b/G-Earth/src/main/java/gearth/extensions/Extension.java
index c987633..4e49c0b 100644
--- a/G-Earth/src/main/java/gearth/extensions/Extension.java
+++ b/G-Earth/src/main/java/gearth/extensions/Extension.java
@@ -1,32 +1,22 @@
package gearth.extensions;
-import gearth.misc.listenerpattern.Observable;
+import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
+import gearth.protocol.connection.HClient;
import gearth.services.Constants;
import gearth.services.extensionhandler.extensions.implementations.network.NetworkExtensionInfo;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
/**
* Created by Jonas on 23/06/18.
*/
-public abstract class Extension implements IExtension {
+public abstract class Extension extends ExtensionBase {
- public interface MessageListener {
- void act(HMessage message);
- }
- public interface FlagsCheckListener {
- void act(String[] args);
- }
-
- protected boolean canLeave; // can you disconnect the ext
- protected boolean canDelete; // can you delete the ext (will be false for some built-in extensions)
+ protected FlagsCheckListener flagRequestCallback = null;
private String[] args;
private boolean isCorrupted = false;
@@ -34,10 +24,9 @@ public abstract class Extension implements IExtension {
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
+ protected PacketInfoManager packetInfoManager = new PacketInfoManager(new ArrayList<>()); // empty
+
private OutputStream out = null;
- private final Map> incomingMessageListeners = new HashMap<>();
- private final Map> outgoingMessageListeners = new HashMap<>();
- private FlagsCheckListener flagRequestCallback = null;
private String getArgument(String[] args, String... arg) {
for (int i = 0; i < args.length - 1; i++) {
@@ -55,8 +44,7 @@ public abstract class Extension implements IExtension {
* @param args arguments
*/
public Extension(String[] args) {
- canLeave = canLeave();
- canDelete = canDelete();
+ super();
//obtain port
this.args = args;
@@ -132,18 +120,23 @@ public abstract class Extension implements IExtension {
.appendBoolean(file != null)
.appendString(file == null ? "": file)
.appendString(cookie == null ? "" : cookie)
- .appendBoolean(canLeave)
- .appendBoolean(canDelete);
+ .appendBoolean(canLeave())
+ .appendBoolean(canDelete());
writeToStream(response.toBytes());
}
else if (packet.headerId() == NetworkExtensionInfo.OUTGOING_MESSAGES_IDS.CONNECTIONSTART) {
String host = packet.readString();
int connectionPort = packet.readInteger();
String hotelVersion = packet.readString();
- String harbleMessagesPath = packet.readString();
- String clientType = packet.readString();
- Constants.UNITY_PACKETS = clientType.toLowerCase().contains("unity");
- onConnectionObservable.fireEvent(l -> l.onConnection(host, connectionPort, hotelVersion, clientType, harbleMessagesPath));
+ String clientIdentifier = packet.readString();
+ HClient clientType = HClient.valueOf(packet.readString());
+ packetInfoManager = PacketInfoManager.readFromPacket(packet);
+
+ Constants.UNITY_PACKETS = clientType == HClient.UNITY;
+ getOnConnectionObservable().fireEvent(l -> l.onConnection(
+ host, connectionPort, hotelVersion,
+ clientIdentifier, clientType, packetInfoManager)
+ );
onStartConnection();
}
else if (packet.headerId() == NetworkExtensionInfo.OUTGOING_MESSAGES_IDS.CONNECTIONEND) {
@@ -171,36 +164,8 @@ public abstract class Extension implements IExtension {
else if (packet.headerId() == NetworkExtensionInfo.OUTGOING_MESSAGES_IDS.PACKETINTERCEPT) {
String stringifiedMessage = packet.readLongString();
HMessage habboMessage = new HMessage(stringifiedMessage);
- HPacket habboPacket = habboMessage.getPacket();
- Map> listeners =
- habboMessage.getDestination() == HMessage.Direction.TOCLIENT ?
- incomingMessageListeners :
- outgoingMessageListeners;
-
- List correctListeners = new ArrayList<>();
-
- synchronized (incomingMessageListeners) {
- synchronized (outgoingMessageListeners) {
- if (listeners.containsKey(-1)) { // registered on all packets
- for (int i = listeners.get(-1).size() - 1; i >= 0; i--) {
- correctListeners.add(listeners.get(-1).get(i));
- }
- }
-
- if (listeners.containsKey(habboPacket.headerId())) {
- for (int i = listeners.get(habboPacket.headerId()).size() - 1; i >= 0; i--) {
- correctListeners.add(listeners.get(habboPacket.headerId()).get(i));
- }
- }
- }
- }
-
- for(MessageListener listener : correctListeners) {
- habboMessage.getPacket().resetReadIndex();
- listener.act(habboMessage);
- }
- habboMessage.getPacket().resetReadIndex();
+ modifyMessage(habboMessage);
HPacket response = new HPacket(NetworkExtensionInfo.INCOMING_MESSAGES_IDS.MANIPULATEDPACKET);
response.appendLongString(habboMessage.stringify());
@@ -249,6 +214,11 @@ public abstract class Extension implements IExtension {
return send(packet, HMessage.Direction.TOSERVER);
}
private boolean send(HPacket packet, HMessage.Direction direction) {
+ if (packet.isCorrupted()) return false;
+
+ if (!packet.isPacketComplete()) packet.completePacket(direction, packetInfoManager);
+ if (!packet.isPacketComplete()) return false;
+
HPacket packet1 = new HPacket(NetworkExtensionInfo.INCOMING_MESSAGES_IDS.SENDMESSAGE);
packet1.appendByte(direction == HMessage.Direction.TOCLIENT ? (byte)0 : (byte)1);
packet1.appendInt(packet.getBytesLength());
@@ -261,37 +231,6 @@ public abstract class Extension implements IExtension {
}
}
- /**
- * Register a listener on a specific packet Type
- * @param direction ToClient or ToServer
- * @param headerId the packet header ID
- * @param messageListener the callback
- */
- public void intercept(HMessage.Direction direction, int headerId, MessageListener messageListener) {
- Map> listeners =
- direction == HMessage.Direction.TOCLIENT ?
- incomingMessageListeners :
- outgoingMessageListeners;
-
- synchronized (listeners) {
- if (!listeners.containsKey(headerId)) {
- listeners.put(headerId, new ArrayList<>());
- }
- }
-
-
- listeners.get(headerId).add(messageListener);
- }
-
- /**
- * Register a listener on all packets
- * @param direction ToClient or ToServer
- * @param messageListener the callback
- */
- public void intercept(HMessage.Direction direction, MessageListener messageListener) {
- intercept(direction, -1, messageListener);
- }
-
/**
* Requests the flags which have been given to G-Earth when it got executed
* For example, you might want this extension to do a specific thing if the flag "-e" was given
@@ -310,15 +249,6 @@ public abstract class Extension implements IExtension {
}
}
-
- /**
- * Write to the console in G-Earth
- * @param s the text to be written
- */
- public void writeToConsole(String s) {
- writeToConsole("black", s, true);
- }
-
/**
* Write to the console in G-Earth
* @param s the text to be written
@@ -346,37 +276,12 @@ public abstract class Extension implements IExtension {
}
}
-
- private boolean isOnClickMethodUsed() {
-
- Class extends Extension> c = getClass();
-
- while (c != Extension.class) {
- try {
- c.getDeclaredMethod("onClick");
- // if it didnt error, onClick exists
- return true;
- } catch (NoSuchMethodException e) {
-// e.printStackTrace();
- }
-
- c = (Class extends Extension>) c.getSuperclass();
- }
-
- return false;
- }
-
/**
* 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(){}
-
/**
* A connection with Habbo has been started
*/
@@ -395,14 +300,4 @@ public abstract class Extension implements IExtension {
return true;
}
- ExtensionInfo getInfoAnnotations() {
- return getClass().getAnnotation(ExtensionInfo.class);
- }
-
-
- private Observable onConnectionObservable = new Observable<>();
- public void onConnect(OnConnectionListener listener){
- onConnectionObservable.addListener(listener);
- }
-
}
diff --git a/G-Earth/src/main/java/gearth/extensions/ExtensionBase.java b/G-Earth/src/main/java/gearth/extensions/ExtensionBase.java
new file mode 100644
index 0000000..060b835
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/ExtensionBase.java
@@ -0,0 +1,130 @@
+package gearth.extensions;
+
+import gearth.misc.listenerpattern.Observable;
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public abstract class ExtensionBase extends IExtension {
+
+ public interface MessageListener {
+ void act(HMessage message);
+ }
+ public interface FlagsCheckListener {
+ void act(String[] args);
+ }
+
+ protected final Map> incomingMessageListeners = new HashMap<>();
+ protected final Map> outgoingMessageListeners = new HashMap<>();
+
+ /**
+ * Register a listener on a specific packet Type
+ * @param direction ToClient or ToServer
+ * @param headerId the packet header ID
+ * @param messageListener the callback
+ */
+ public void intercept(HMessage.Direction direction, int headerId, MessageListener messageListener) {
+ Map> listeners =
+ direction == HMessage.Direction.TOCLIENT ?
+ incomingMessageListeners :
+ outgoingMessageListeners;
+
+ synchronized (listeners) {
+ if (!listeners.containsKey(headerId)) {
+ listeners.put(headerId, new ArrayList<>());
+ }
+ }
+
+
+ listeners.get(headerId).add(messageListener);
+ }
+
+ /**
+ * Register a listener on all packets
+ * @param direction ToClient or ToServer
+ * @param messageListener the callback
+ */
+ public void intercept(HMessage.Direction direction, MessageListener messageListener) {
+ intercept(direction, -1, messageListener);
+ }
+
+ @Override
+ public void writeToConsole(String s) {
+ writeToConsole("black", s);
+ }
+
+ protected boolean isOnClickMethodUsed() {
+ Class extends ExtensionBase> c = getClass();
+ while (c != Extension.class) {
+ try {
+ c.getDeclaredMethod("onClick");
+ // if it didnt error, onClick exists
+ return true;
+ } catch (NoSuchMethodException e) {
+// e.printStackTrace();
+ }
+
+ c = (Class extends ExtensionBase>) c.getSuperclass();
+ }
+ return false;
+ }
+
+ public void modifyMessage(HMessage habboMessage) {
+ HPacket habboPacket = habboMessage.getPacket();
+
+ Map> listeners =
+ habboMessage.getDestination() == HMessage.Direction.TOCLIENT ?
+ incomingMessageListeners :
+ outgoingMessageListeners;
+
+ List correctListeners = new ArrayList<>();
+
+ synchronized (incomingMessageListeners) {
+ synchronized (outgoingMessageListeners) {
+ if (listeners.containsKey(-1)) { // registered on all packets
+ for (int i = listeners.get(-1).size() - 1; i >= 0; i--) {
+ correctListeners.add(listeners.get(-1).get(i));
+ }
+ }
+
+ if (listeners.containsKey(habboPacket.headerId())) {
+ for (int i = listeners.get(habboPacket.headerId()).size() - 1; i >= 0; i--) {
+ correctListeners.add(listeners.get(habboPacket.headerId()).get(i));
+ }
+ }
+ }
+ }
+
+ for(MessageListener listener : correctListeners) {
+ habboMessage.getPacket().resetReadIndex();
+ listener.act(habboMessage);
+ }
+ habboMessage.getPacket().resetReadIndex();
+ }
+
+ /**
+ * The application got doubleclicked from the G-Earth interface. Doing something here is optional
+ */
+ @Override
+ void onClick() {
+
+ }
+
+ @Override
+ protected ExtensionInfo getInfoAnnotations() {
+ return getClass().getAnnotation(ExtensionInfo.class);
+ }
+
+ private Observable onConnectionObservable = new Observable<>();
+ public void onConnect(OnConnectionListener listener){
+ onConnectionObservable.addListener(listener);
+ }
+
+ Observable getOnConnectionObservable() {
+ return onConnectionObservable;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java b/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java
index 145733c..5310cd0 100644
--- a/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java
+++ b/G-Earth/src/main/java/gearth/extensions/ExtensionForm.java
@@ -8,9 +8,9 @@ import gearth.protocol.HPacket;
/**
* Created by Jonas on 22/09/18.
*/
-public abstract class ExtensionForm implements IExtension {
+public abstract class ExtensionForm extends ExtensionBase {
- volatile Extension extension;
+ volatile ExtensionBase extension;
protected volatile Stage primaryStage;
protected static void runExtensionForm(String[] args, Class extends ExtensionForm> extension) {
@@ -59,7 +59,7 @@ public abstract class ExtensionForm implements IExtension {
/**
* The application got doubleclicked from the G-Earth interface. Doing something here is optional
*/
- protected void onClick(){
+ public void onClick(){
Platform.runLater(() -> {
primaryStage.show();
primaryStage.requestFocus();
diff --git a/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java b/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java
index 0eec47b..920f02a 100644
--- a/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java
+++ b/G-Earth/src/main/java/gearth/extensions/ExtensionFormLauncher.java
@@ -5,7 +5,7 @@ import javafx.application.Platform;
import javafx.stage.Stage;
/**
- * Created by Jeunez on 6/11/2018.
+ * Created by Jonas on 6/11/2018.
*/
public class ExtensionFormLauncher extends Application {
@@ -19,7 +19,7 @@ public class ExtensionFormLauncher extends Application {
ExtensionForm creator = extension.newInstance();
ExtensionForm extensionForm = creator.launchForm(primaryStage);
- extensionForm.extension = new Extension(args) {
+ Extension extension = new Extension(args) {
@Override
protected void initExtension() {
extensionForm.initExtension();
@@ -41,7 +41,7 @@ public class ExtensionFormLauncher extends Application {
}
@Override
- ExtensionInfo getInfoAnnotations() {
+ protected ExtensionInfo getInfoAnnotations() {
return extInfo;
}
@@ -55,9 +55,11 @@ public class ExtensionFormLauncher extends Application {
return extensionForm.canDelete();
}
};
+ extensionForm.extension = extension;
+
extensionForm.primaryStage = primaryStage;
Thread t = new Thread(() -> {
- extensionForm.extension.run();
+ extension.run();
//when the extension has ended, close this process
System.exit(0);
});
diff --git a/G-Earth/src/main/java/gearth/extensions/IExtension.java b/G-Earth/src/main/java/gearth/extensions/IExtension.java
index 8040bce..3b8ae89 100644
--- a/G-Earth/src/main/java/gearth/extensions/IExtension.java
+++ b/G-Earth/src/main/java/gearth/extensions/IExtension.java
@@ -3,15 +3,22 @@ package gearth.extensions;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
-public interface IExtension {
+public abstract class IExtension {
- boolean sendToClient(HPacket packet);
- boolean sendToServer(HPacket packet);
- void intercept(HMessage.Direction direction, int headerId, Extension.MessageListener messageListener);
- void intercept(HMessage.Direction direction, Extension.MessageListener messageListener);
- boolean requestFlags(Extension.FlagsCheckListener flagRequestCallback);
- void writeToConsole(String colorClass, String s);
- void writeToConsole(String s);
- void onConnect(OnConnectionListener listener);
+ public abstract boolean sendToClient(HPacket packet);
+ public abstract boolean sendToServer(HPacket packet);
+ public abstract void intercept(HMessage.Direction direction, int headerId, Extension.MessageListener messageListener);
+ public abstract void intercept(HMessage.Direction direction, Extension.MessageListener messageListener);
+ public abstract boolean requestFlags(Extension.FlagsCheckListener flagRequestCallback);
+ public abstract void writeToConsole(String colorClass, String s);
+ public abstract void writeToConsole(String s);
+ public abstract void onConnect(OnConnectionListener listener);
+ abstract void initExtension();
+ abstract void onClick();
+ abstract void onStartConnection();
+ abstract void onEndConnection();
+ abstract ExtensionInfo getInfoAnnotations();
+ abstract boolean canLeave();
+ abstract boolean canDelete();
}
diff --git a/G-Earth/src/main/java/gearth/extensions/InternalExtension.java b/G-Earth/src/main/java/gearth/extensions/InternalExtension.java
new file mode 100644
index 0000000..5f870d2
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/InternalExtension.java
@@ -0,0 +1,68 @@
+package gearth.extensions;
+
+import gearth.Main;
+import gearth.extensions.ExtensionBase;
+import gearth.extensions.IExtension;
+import gearth.protocol.HPacket;
+
+
+public class InternalExtension extends ExtensionBase {
+
+ public interface InternalExtensionCommunicator {
+ void sendToClient(HPacket packet);
+ void sendToServer(HPacket packet);
+ void writeToConsole(String s);
+ }
+
+ private InternalExtensionCommunicator communicator = null;
+
+ public void setCommunicator(InternalExtensionCommunicator communicator) {
+ this.communicator = communicator;
+ }
+
+ @Override
+ public boolean sendToClient(HPacket packet) {
+ communicator.sendToClient(packet);
+ return true;
+ }
+
+ @Override
+ public boolean sendToServer(HPacket packet) {
+ communicator.sendToServer(packet);
+ return true;
+ }
+
+ @Override
+ public boolean requestFlags(FlagsCheckListener flagRequestCallback) {
+ flagRequestCallback.act(Main.args);
+ return true;
+ }
+
+ @Override
+ public void writeToConsole(String colorClass, String s) {
+ String text = "[" + colorClass + "]" + getInfoAnnotations().Title() + " --> " + s;
+ communicator.writeToConsole(text);
+ }
+
+ // to be maybe overwritten
+ @Override
+ protected void initExtension() { }
+
+ // to be maybe overwritten
+ @Override
+ protected void onStartConnection() {}
+
+ // to be maybe overwritten
+ @Override
+ protected void onEndConnection() {}
+
+ @Override
+ protected boolean canLeave() {
+ return false;
+ }
+
+ @Override
+ protected boolean canDelete() {
+ return false;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/extensions/InternalExtensionBuilder.java b/G-Earth/src/main/java/gearth/extensions/InternalExtensionBuilder.java
new file mode 100644
index 0000000..8f90d79
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/InternalExtensionBuilder.java
@@ -0,0 +1,145 @@
+package gearth.extensions;
+
+
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+import gearth.protocol.connection.HClient;
+import gearth.services.extensionhandler.extensions.ExtensionType;
+import gearth.services.extensionhandler.extensions.GEarthExtension;
+
+// wraps internal GEarthExtension class to IExtension interface
+// to allow internal extensions that follow the same remote-extensions interface
+public class InternalExtensionBuilder extends GEarthExtension {
+
+ private final InternalExtension extension;
+
+ public InternalExtensionBuilder(InternalExtension extension) {
+ this.extension = extension;
+ extension.setCommunicator(new InternalExtension.InternalExtensionCommunicator() {
+ @Override
+ public void sendToClient(HPacket packet) {
+ sendMessage(HMessage.Direction.TOCLIENT, packet);
+ }
+
+ @Override
+ public void sendToServer(HPacket packet) {
+ sendMessage(HMessage.Direction.TOSERVER, packet);
+ }
+
+ @Override
+ public void writeToConsole(String s) {
+ log(s);
+ }
+ });
+ }
+
+ @Override
+ public String getAuthor() {
+ return extension.getInfoAnnotations().Author();
+ }
+
+ @Override
+ public String getDescription() {
+ return extension.getInfoAnnotations().Description();
+ }
+
+ @Override
+ public String getTitle() {
+ return extension.getInfoAnnotations().Title();
+ }
+
+ @Override
+ public String getVersion() {
+ return extension.getInfoAnnotations().Version();
+ }
+
+ @Override
+ public boolean isFireButtonUsed() {
+ Class extends InternalExtension > c = extension.getClass();
+
+ while (c != InternalExtension.class) {
+ try {
+ c.getDeclaredMethod("onClick");
+ return true;
+ } catch (NoSuchMethodException e) {
+// e.printStackTrace();
+ }
+
+ c = (Class extends InternalExtension>) c.getSuperclass();
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean isDeleteButtonVisible() {
+ return extension.canDelete();
+ }
+
+ @Override
+ public boolean isLeaveButtonVisible() {
+ return extension.canLeave();
+ }
+
+ @Override
+ public boolean isInstalledExtension() {
+ return false;
+ }
+
+ @Override
+ public void doubleclick() {
+ extension.onClick();
+ }
+
+ @Override
+ public void packetIntercept(HMessage hMessage) {
+ extension.modifyMessage(hMessage);
+ sendManipulatedPacket(hMessage);
+ }
+
+ @Override
+ public void provideFlags(String[] flags) {
+ // no need
+ }
+
+ @Override
+ public void connectionStart(String host, int port, String hotelVersion, String clientIdentifier, HClient clientType, PacketInfoManager packetInfoManager) {
+ extension.getOnConnectionObservable().fireEvent(l -> l.onConnection(
+ host, port, hotelVersion,
+ clientIdentifier, clientType, packetInfoManager)
+ );
+ extension.onStartConnection();
+ }
+
+ @Override
+ public void connectionEnd() {
+ extension.onEndConnection();
+ }
+
+ @Override
+ public void init() {
+ extension.initExtension();
+ }
+
+ @Override
+ public void close() {
+ // no need in internal ext
+ }
+
+ @Override
+ public void packetToStringResponse(String string, String expression) {
+ // no need in java ext
+ }
+
+ @Override
+ public void stringToPacketResponse(HPacket packet) {
+ // no need in java ext
+ }
+
+ @Override
+ public ExtensionType extensionType() {
+ return ExtensionType.INTERNAL;
+ }
+
+}
diff --git a/G-Earth/src/main/java/gearth/extensions/InternalExtensionFormBuilder.java b/G-Earth/src/main/java/gearth/extensions/InternalExtensionFormBuilder.java
new file mode 100644
index 0000000..ddf5358
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/InternalExtensionFormBuilder.java
@@ -0,0 +1,78 @@
+package gearth.extensions;
+
+import gearth.services.extensionhandler.extensions.GEarthExtension;
+import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducerObserver;
+import javafx.application.Platform;
+import javafx.stage.Stage;
+
+public class InternalExtensionFormBuilder {
+
+ public T launch(Class extensionClass, ExtensionProducerObserver observer) {
+ try {
+ ExtensionInfo extInfo = extensionClass.getAnnotation(ExtensionInfo.class);
+ T creator = extensionClass.newInstance();
+
+ Stage stage = new Stage();
+ T extensionForm = (T)(creator.launchForm(stage));
+
+ InternalExtension internalExtension = new InternalExtension() {
+ @Override
+ protected void initExtension() {
+ extensionForm.initExtension();
+ }
+
+ @Override
+ protected void onClick() {
+ extensionForm.onClick();
+ }
+
+ @Override
+ protected void onStartConnection() {
+ extensionForm.onStartConnection();
+ }
+
+ @Override
+ protected void onEndConnection() {
+ extensionForm.onEndConnection();
+ }
+
+ @Override
+ protected ExtensionInfo getInfoAnnotations() {
+ return extInfo;
+ }
+
+ @Override
+ protected boolean canLeave() {
+ return extensionForm.canLeave();
+ }
+
+ @Override
+ protected boolean canDelete() {
+ return extensionForm.canDelete();
+ }
+ };
+ extensionForm.extension = internalExtension;
+ extensionForm.primaryStage = stage;
+
+ GEarthExtension gEarthExtension = new InternalExtensionBuilder(internalExtension);
+ observer.onExtensionProduced(gEarthExtension);
+
+
+ Platform.setImplicitExit(false);
+
+ stage.setOnCloseRequest(event -> {
+ event.consume();
+ Platform.runLater(() -> {
+ stage.hide();
+ extensionForm.onHide();
+ });
+ });
+
+ return extensionForm;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/extensions/OnConnectionListener.java b/G-Earth/src/main/java/gearth/extensions/OnConnectionListener.java
index cbb63b0..07b7f58 100644
--- a/G-Earth/src/main/java/gearth/extensions/OnConnectionListener.java
+++ b/G-Earth/src/main/java/gearth/extensions/OnConnectionListener.java
@@ -1,5 +1,8 @@
package gearth.extensions;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.connection.HClient;
+
public interface OnConnectionListener {
- void onConnection(String host, int port, String hotelversion, String clientType, String harbleMessagesPath);
+ void onConnection(String host, int port, String hotelversion, String clientIdentifier, HClient clientType, PacketInfoManager packetInfoManager);
}
diff --git a/G-Earth/src/main/java/gearth/extensions/extra/harble/HashSupport.java b/G-Earth/src/main/java/gearth/extensions/extra/harble/HashSupport.java
deleted file mode 100644
index c4dd705..0000000
--- a/G-Earth/src/main/java/gearth/extensions/extra/harble/HashSupport.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package gearth.extensions.extra.harble;
-
-import gearth.extensions.Extension;
-import gearth.extensions.IExtension;
-import gearth.misc.harble_api.HarbleAPI;
-import gearth.protocol.HMessage;
-import gearth.protocol.HPacket;
-
-import java.io.File;
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Created by Jonas on 10/11/2018.
- */
-public class HashSupport {
-
- private final Object lock = new Object();
-
- private HarbleAPI harbleAPI = new HarbleAPI(""); //empty
- private Map> incomingMessageListeners = new HashMap<>();
- private Map> outgoingMessageListeners = new HashMap<>();
-
- private IExtension extension;
-
- public HashSupport(IExtension extension) {
- this.extension = extension;
-
- extension.onConnect((host, port, hotelversion, clientType, cachePath) -> {
-// synchronized (lock) {
- harbleAPI = new HarbleAPI(new File(cachePath));
-// }
- });
-
- extension.intercept(HMessage.Direction.TOSERVER, message -> {
-// synchronized (lock) {
- HarbleAPI.HarbleMessage haMessage = harbleAPI.getHarbleMessageFromHeaderId(HMessage.Direction.TOSERVER, message.getPacket().headerId());
- if (haMessage != null) {
- List listeners_hash = outgoingMessageListeners.get(haMessage.getHash());
- List listeners_name = outgoingMessageListeners.get(haMessage.getName());
- if (listeners_hash != null) {
- for (Extension.MessageListener listener : listeners_hash) {
- listener.act(message);
- message.getPacket().resetReadIndex();
- }
- }
- if (listeners_name != null) {
- for (Extension.MessageListener listener : listeners_name) {
- listener.act(message);
- message.getPacket().resetReadIndex();
- }
- }
- }
-// }
- });
- extension.intercept(HMessage.Direction.TOCLIENT, message -> {
-// synchronized (lock) {
- HarbleAPI.HarbleMessage haMessage = harbleAPI.getHarbleMessageFromHeaderId(HMessage.Direction.TOCLIENT, message.getPacket().headerId());
- if (haMessage != null) {
- List listeners_hash = incomingMessageListeners.get(haMessage.getHash());
- List listeners_name = incomingMessageListeners.get(haMessage.getName());
- if (listeners_hash != null) {
- for (Extension.MessageListener listener : listeners_hash) {
- listener.act(message);
- message.getPacket().resetReadIndex();
- }
- }
- if (listeners_name != null) {
- for (Extension.MessageListener listener : listeners_name) {
- listener.act(message);
- message.getPacket().resetReadIndex();
- }
- }
- }
-// }
- });
- }
-
- public void intercept(HMessage.Direction direction, String hashOrName, Extension.MessageListener messageListener) {
- Map> messageListeners =
- (direction == HMessage.Direction.TOSERVER
- ? outgoingMessageListeners
- : incomingMessageListeners);
-
- messageListeners.computeIfAbsent(hashOrName, k -> new ArrayList<>());
- messageListeners.get(hashOrName).add(messageListener);
- }
-
- private boolean send(HMessage.Direction direction, String hashOrName, Object... objects) {
- int headerId;
- HarbleAPI.HarbleMessage fromname = harbleAPI.getHarbleMessageFromName(direction, hashOrName);
- if (fromname != null) {
- headerId = fromname.getHeaderId();
- }
- else {
- List possibilities = harbleAPI.getHarbleMessagesFromHash(direction, hashOrName);
- if (possibilities.size() == 0) return false;
- headerId = possibilities.get(0).getHeaderId();
- }
-
- try {
- HPacket packetToSend = new HPacket(headerId, objects);
-
- return (direction == HMessage.Direction.TOCLIENT
- ? extension.sendToClient(packetToSend)
- : extension.sendToServer(packetToSend));
- }
- catch (InvalidParameterException e) {
- return false;
- }
- }
-
- /**
- *
- * @return if no errors occurred (invalid hash/invalid parameters/connection error)
- */
- public boolean sendToClient(String hashOrName, Object... objects) {
- return send(HMessage.Direction.TOCLIENT, hashOrName, objects);
- }
-
- /**
- *
- * @return if no errors occurred (invalid hash/invalid parameters/connection error)
- */
- public boolean sendToServer(String hashOrName, Object... objects) {
- return send(HMessage.Direction.TOSERVER, hashOrName, objects);
- }
-
- public HarbleAPI getHarbleAPI() {
- return harbleAPI;
- }
-}
diff --git a/G-Earth/src/main/java/gearth/extensions/extra/harble/ChatConsole.java b/G-Earth/src/main/java/gearth/extensions/extra/tools/ChatConsole.java
similarity index 74%
rename from G-Earth/src/main/java/gearth/extensions/extra/harble/ChatConsole.java
rename to G-Earth/src/main/java/gearth/extensions/extra/tools/ChatConsole.java
index ddc339a..cde0c8c 100644
--- a/G-Earth/src/main/java/gearth/extensions/extra/harble/ChatConsole.java
+++ b/G-Earth/src/main/java/gearth/extensions/extra/tools/ChatConsole.java
@@ -1,8 +1,7 @@
-package gearth.extensions.extra.harble;
+package gearth.extensions.extra.tools;
import gearth.extensions.ExtensionInfo;
import gearth.extensions.IExtension;
-import gearth.extensions.OnConnectionListener;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
@@ -18,31 +17,33 @@ public class ChatConsole {
private volatile int chatid;
private volatile String name;
- private volatile HashSupport hashSupport;
+ private volatile PacketInfoSupport packetInfoSupport;
private volatile String infoMessage;
private volatile boolean firstTime = true;
private volatile Observable chatInputObservable = new Observable<>();
- public ChatConsole(final HashSupport hashSupport, IExtension extension) {
- this(hashSupport, extension, null);
+ public ChatConsole(final PacketInfoSupport packetInfoSupport, IExtension extension) {
+ this(packetInfoSupport, extension, null);
}
/**
* infomessage will be used as response for :info and for initialize
- * @param hashSupport
+ * @param packetInfoSupport
* @param extension
* @param infoMessage
*/
- public ChatConsole(final HashSupport hashSupport, IExtension extension, String infoMessage) {
- this.hashSupport = hashSupport;
+ public ChatConsole(final PacketInfoSupport packetInfoSupport, IExtension extension, String infoMessage) {
+ this.packetInfoSupport = packetInfoSupport;
this.name = extension.getClass().getAnnotation(ExtensionInfo.class).Title();
chatid = (this.name.hashCode() % 300000000) + 300000000;
this.infoMessage = infoMessage;
final boolean[] doOncePerConnection = {false};
- extension.onConnect((s, i, s1, ct, h1) -> doOncePerConnection[0] = true);
+ extension.onConnect((host, port, hotelversion, clientIdentifier, clientType, packetInfoManager) ->
+ doOncePerConnection[0] = true
+ );
extension.intercept(HMessage.Direction.TOSERVER, hMessage -> {
// if the first packet on init is not 4000, the extension was already running, so we open the chat instantly
@@ -55,7 +56,7 @@ public class ChatConsole {
}
});
- hashSupport.intercept(HMessage.Direction.TOCLIENT, "FriendListFragment", hMessage -> {
+ packetInfoSupport.intercept(HMessage.Direction.TOCLIENT, "FriendListFragment", hMessage -> {
if (doOncePerConnection[0]) {
doOncePerConnection[0] = false;
@@ -71,7 +72,7 @@ public class ChatConsole {
}
});
- hashSupport.intercept(HMessage.Direction.TOSERVER, "SendMsg", hMessage -> {
+ packetInfoSupport.intercept(HMessage.Direction.TOSERVER, "SendMsg", hMessage -> {
HPacket packet = hMessage.getPacket();
if (packet.readInteger() == chatid) {
hMessage.setBlocked(true);
@@ -87,7 +88,7 @@ public class ChatConsole {
}
private void createChat() {
- hashSupport.sendToClient("FriendListUpdate",
+ packetInfoSupport.sendToClient("FriendListUpdate",
0, 1, 0, chatid, " [G-Earth] - " + name,
1, true, false, "ha-1015-64.hd-209-30.cc-260-64.ch-235-64.sh-305-64.lg-285-64",
0, "", 0, true, false, true, ""
@@ -100,10 +101,10 @@ public class ChatConsole {
public void writeOutput(String string, boolean asInvite) {
if (asInvite) {
- hashSupport.sendToClient("RoomInvite", chatid, string);
+ packetInfoSupport.sendToClient("RoomInvite", chatid, string);
}
else {
- hashSupport.sendToClient("NewConsole", chatid, string, 0, "");
+ packetInfoSupport.sendToClient("NewConsole", chatid, string, 0, "");
}
}
diff --git a/G-Earth/src/main/java/gearth/extensions/extra/harble/ChatInputListener.java b/G-Earth/src/main/java/gearth/extensions/extra/tools/ChatInputListener.java
similarity index 65%
rename from G-Earth/src/main/java/gearth/extensions/extra/harble/ChatInputListener.java
rename to G-Earth/src/main/java/gearth/extensions/extra/tools/ChatInputListener.java
index a9a933a..4e097a8 100644
--- a/G-Earth/src/main/java/gearth/extensions/extra/harble/ChatInputListener.java
+++ b/G-Earth/src/main/java/gearth/extensions/extra/tools/ChatInputListener.java
@@ -1,4 +1,4 @@
-package gearth.extensions.extra.harble;
+package gearth.extensions.extra.tools;
public interface ChatInputListener {
void inputEntered(String input);
diff --git a/G-Earth/src/main/java/gearth/extensions/extra/tools/PacketInfoSupport.java b/G-Earth/src/main/java/gearth/extensions/extra/tools/PacketInfoSupport.java
new file mode 100644
index 0000000..b0d256a
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/extensions/extra/tools/PacketInfoSupport.java
@@ -0,0 +1,116 @@
+package gearth.extensions.extra.tools;
+
+import gearth.extensions.Extension;
+import gearth.extensions.IExtension;
+import gearth.services.packet_info.PacketInfo;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+
+import java.security.InvalidParameterException;
+import java.util.*;
+
+/**
+ * Created by Jonas on 10/11/2018.
+ */
+public class PacketInfoSupport {
+
+ private final Object lock = new Object();
+
+ private PacketInfoManager packetInfoManager = new PacketInfoManager(new ArrayList<>()); //empty
+ private Map> incomingMessageListeners = new HashMap<>();
+ private Map> outgoingMessageListeners = new HashMap<>();
+
+ private IExtension extension;
+
+ public PacketInfoSupport(IExtension extension) {
+ this.extension = extension;
+
+ extension.onConnect((host, port, hotelversion, clientIdentifier, clientType, packetInfoManager) ->
+ this.packetInfoManager = packetInfoManager
+ );
+
+ extension.intercept(HMessage.Direction.TOSERVER, message -> onReceivePacket(HMessage.Direction.TOSERVER, message));
+ extension.intercept(HMessage.Direction.TOCLIENT, message -> onReceivePacket(HMessage.Direction.TOCLIENT, message));
+ }
+
+ private void onReceivePacket(HMessage.Direction direction, HMessage message) {
+ Set callbacks = new HashSet<>();
+ Map> messageListeners =
+ (direction == HMessage.Direction.TOSERVER
+ ? outgoingMessageListeners
+ : incomingMessageListeners);
+
+ List packetInfos = packetInfoManager.getAllPacketInfoFromHeaderId(HMessage.Direction.TOCLIENT, message.getPacket().headerId());
+
+ for (PacketInfo packetInfo : packetInfos) {
+ List listeners_hash = messageListeners.get(packetInfo.getHash());
+ List listeners_name = messageListeners.get(packetInfo.getName());
+ if (listeners_hash != null) {
+ callbacks.addAll(listeners_hash);
+ }
+ if (listeners_name != null) {
+ callbacks.addAll(listeners_name);
+ }
+ }
+
+ for (Extension.MessageListener listener : callbacks) {
+ listener.act(message);
+ message.getPacket().resetReadIndex();
+ }
+ }
+
+ public void intercept(HMessage.Direction direction, String hashOrName, Extension.MessageListener messageListener) {
+ Map> messageListeners =
+ (direction == HMessage.Direction.TOSERVER
+ ? outgoingMessageListeners
+ : incomingMessageListeners);
+
+ messageListeners.computeIfAbsent(hashOrName, k -> new ArrayList<>());
+ messageListeners.get(hashOrName).add(messageListener);
+ }
+
+ private boolean send(HMessage.Direction direction, String hashOrName, Object... objects) {
+ int headerId;
+ PacketInfo fromname = packetInfoManager.getPacketInfoFromName(direction, hashOrName);
+ if (fromname != null) {
+ headerId = fromname.getHeaderId();
+ }
+ else {
+ PacketInfo fromHash = packetInfoManager.getPacketInfoFromHash(direction, hashOrName);
+ if (fromHash == null) return false;
+ headerId = fromHash.getHeaderId();
+ }
+
+ try {
+ HPacket packetToSend = new HPacket(headerId, objects);
+
+ return (direction == HMessage.Direction.TOCLIENT
+ ? extension.sendToClient(packetToSend)
+ : extension.sendToServer(packetToSend));
+ }
+ catch (InvalidParameterException e) {
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @return if no errors occurred (invalid hash/invalid parameters/connection error)
+ */
+ public boolean sendToClient(String hashOrName, Object... objects) {
+ return send(HMessage.Direction.TOCLIENT, hashOrName, objects);
+ }
+
+ /**
+ *
+ * @return if no errors occurred (invalid hash/invalid parameters/connection error)
+ */
+ public boolean sendToServer(String hashOrName, Object... objects) {
+ return send(HMessage.Direction.TOSERVER, hashOrName, objects);
+ }
+
+ public PacketInfoManager getPacketInfoManager() {
+ return packetInfoManager;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/misc/harble_api/HarbleAPI.java b/G-Earth/src/main/java/gearth/misc/harble_api/HarbleAPI.java
deleted file mode 100644
index 8333483..0000000
--- a/G-Earth/src/main/java/gearth/misc/harble_api/HarbleAPI.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package gearth.misc.harble_api;
-
-import gearth.misc.Cacher;
-import gearth.protocol.HMessage;
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Created by Jonas on 10/11/2018.
- */
-public class HarbleAPI {
-
- public class HarbleMessage {
- private HMessage.Direction destination;
- private int headerId;
- private String hash;
- private String name;
- private String structure;
-
- //name can be NULL
- public HarbleMessage(HMessage.Direction destination, int headerId, String hash, String name, String structure) {
- this.destination = destination;
- this.headerId = headerId;
- this.hash = hash;
- this.name = (name == null || name.equals("null") ? null : name);
- this.structure = (structure == null || structure.equals("null") ? null : structure);
- }
-
- public String getName() {
- return name;
- }
-
- public int getHeaderId() {
- return headerId;
- }
-
- public HMessage.Direction getDestination() {
- return destination;
- }
-
- public String getHash() {
- return hash;
- }
-
- public String getStructure() {
- return structure;
- }
-
- public String toString() {
- String s = (headerId + ": " + "[" + hash + "][" + name + "][" + structure + "]");
- return s;
- }
- }
-
- private Map headerIdToMessage_incoming = new HashMap<>();
- private Map headerIdToMessage_outgoing = new HashMap<>();
-
- private Map> hashToMessage_incoming = new HashMap<>();
- private Map> hashToMessage_outgoing = new HashMap<>();
-
- private Map nameToMessage_incoming = new HashMap<>();
- private Map nameToMessage_outgoing = new HashMap<>();
-
- private boolean success = false;
- private String fullPath = null;
-
- /**
- * cache file must be generated first within G-Earth, inb4 20 extensions requesting it at the same time
- *
- * @param hotelversion
- */
-
- public static HarbleAPI get(String hotelversion) {
- HarbleAPI wannabe = new HarbleAPI(hotelversion);
- if (!wannabe.success) {
- return null;
- }
- return wannabe;
- }
-
- public HarbleAPI(String hotelversion) {
- String possibleCachedMessagesPath = HarbleAPIFetcher.CACHE_PREFIX + hotelversion;
- if (Cacher.cacheFileExists(possibleCachedMessagesPath)) {
- JSONObject object = Cacher.getCacheContents(possibleCachedMessagesPath);
- success = true;
- fullPath = Cacher.getCacheDir() + File.separator + possibleCachedMessagesPath;
- parse(object);
- }
- }
-
- public HarbleAPI(File f) {
- if (f.exists() && !f.isDirectory()) {
- try {
- String contents = String.join("\n", Files.readAllLines(f.toPath()));
- JSONObject object = new JSONObject(contents);
- success = true;
- fullPath = f.getAbsolutePath();
- parse(object);
-
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private void addMessage(HMessage.Direction direction, JSONObject object) {
- String name;
- String hash;
- try { name = object.getString("Name"); }
- catch (Exception e) { name = null; }
- try { hash = object.getString("Hash"); }
- catch (Exception e) { hash = null; }
-
-
- int headerId = object.getInt("Id");
-
- String structure;
- try {
- structure = object.getString("Structure");
- } catch (Exception e) {
- structure = null;
- }
-
-
- HarbleMessage message = new HarbleMessage(direction, headerId, hash, name, structure);
-
-
- Map headerIdToMessage =
- message.getDestination() == HMessage.Direction.TOCLIENT
- ? headerIdToMessage_incoming :
- headerIdToMessage_outgoing;
-
- Map> hashToMessage =
- message.getDestination() == HMessage.Direction.TOCLIENT
- ? hashToMessage_incoming
- : hashToMessage_outgoing;
-
- Map nameToMessag =
- message.getDestination() == HMessage.Direction.TOCLIENT
- ? nameToMessage_incoming
- : nameToMessage_outgoing;
-
- headerIdToMessage.put(message.getHeaderId(), message);
- hashToMessage.computeIfAbsent(message.getHash(), k -> new ArrayList<>());
- hashToMessage.get(message.getHash()).add(message);
- if (message.getName() != null && !message.getName().equals("null")) {
- nameToMessag.put(message.getName(), message);
- }
- }
-
- private void parse(JSONObject object) {
- try {
- JSONArray incoming = object.getJSONArray("Incoming");
- JSONArray outgoing = object.getJSONArray("Outgoing");
-
- if (incoming != null && outgoing != null) {
- for (int i = 0; i < incoming.length(); i++) {
- try {
- JSONObject message = incoming.getJSONObject(i);
- addMessage(HMessage.Direction.TOCLIENT, message);
- }
- catch (Exception e){
- e.printStackTrace();
- }
- }
- for (int i = 0; i < outgoing.length(); i++) {
- try{
- JSONObject message = outgoing.getJSONObject(i);
- addMessage(HMessage.Direction.TOSERVER, message);
- }
- catch (Exception e){
- e.printStackTrace();
- }
- }
- }
- } catch (Exception e) {
- success = false;
- }
- }
-
- public HarbleMessage getHarbleMessageFromHeaderId(HMessage.Direction direction, int headerId) {
- Map headerIdToMessage =
- (direction == HMessage.Direction.TOSERVER
- ? headerIdToMessage_outgoing
- : headerIdToMessage_incoming);
-
- return headerIdToMessage.get(headerId);
- }
-
- public List getHarbleMessagesFromHash(HMessage.Direction direction, String hash) {
- Map> hashToMessage =
- (direction == HMessage.Direction.TOSERVER
- ? hashToMessage_outgoing
- : hashToMessage_incoming);
-
- List result = hashToMessage.get(hash);
- return result == null ? new ArrayList<>() : result;
- }
-
- public HarbleMessage getHarbleMessageFromName(HMessage.Direction direction, String name) {
- Map nameToMessage =
- (direction == HMessage.Direction.TOSERVER
- ? nameToMessage_outgoing
- : nameToMessage_incoming);
-
- return nameToMessage.get(name);
- }
-
- public String getPath() {
- if (success) {
- return fullPath;
- }
- return "null";
- }
-
-}
diff --git a/G-Earth/src/main/java/gearth/misc/harble_api/HarbleAPIFetcher.java b/G-Earth/src/main/java/gearth/misc/harble_api/HarbleAPIFetcher.java
deleted file mode 100644
index 4c54684..0000000
--- a/G-Earth/src/main/java/gearth/misc/harble_api/HarbleAPIFetcher.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package gearth.misc.harble_api;
-
-import gearth.Main;
-import gearth.misc.Cacher;
-import gearth.protocol.HMessage;
-import org.jsoup.Connection;
-import org.jsoup.Jsoup;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-/**
- * Created by Jonas on 10/11/2018.
- */
-
-/**
- * Ok the usage of this class is pretty shitty so I'm just gonna add some documentation here
- *
- * What this class does is fetching the revision (if needed) from the API, this is the only class with communication with the
- * actual API. Then the result (if any) gets cached.
- *
- * The method "fetch(xxx);" needs to be called exactly once at the moment a new connection has been made.
- *
- * However, at that same moment the Extension class needs to send the "startConnection" signal to the extensions, and we want to make sure
- * that the cached revision is already available at the moment the extensions get initialized with a new connection. That's why the
- * fetch() method here only gets called by the extension class as that's the only way to ensure this method gets called BEFORE the extensions
- * start. (bc im lazy and dont wanna rewrite code too)
- *
- *
- * the "HARBLEAPI" object contains the latest fetched object and is ensured to be up-to-date with the current connection
- */
-public class HarbleAPIFetcher {
-
- public static final String CACHE_PREFIX = "HARBLE_API-";
- public static final String HARBLE_API_URL = "https://api.harble.net/messages/$hotelversion$.json";
-
- //latest fetched
- public static HarbleAPI HARBLEAPI = null;
-
- public synchronized static void fetch(String hotelversion, String clientType) {
- // if unity
- if (clientType.toLowerCase().contains("unity")) {
- try {
- HARBLEAPI = new HarbleAPI(
- new File(new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI())
- .getParentFile(), "messages.json"
- )
- );
- } catch (URISyntaxException e) {
- HARBLEAPI = null;
- }
- return;
- }
-
- String cacheName = CACHE_PREFIX + hotelversion;
-
- if (Cacher.cacheFileExists(cacheName)) {
- HARBLEAPI = new HarbleAPI(hotelversion);
- }
- else {
- Connection connection = Jsoup.connect(HARBLE_API_URL.replace("$hotelversion$", hotelversion)).ignoreContentType(true);
- try {
- connection.timeout(3000);
- Connection.Response response = connection.execute();
- if (response.statusCode() == 200) {
- String messagesBodyJson = response.body();
- Cacher.updateCache(messagesBodyJson, cacheName);
- HARBLEAPI = new HarbleAPI(hotelversion);
- }
- else {
- HARBLEAPI = null;
- }
- } catch (IOException e) {
- HARBLEAPI = null;
- }
-
- }
- }
-}
\ No newline at end of file
diff --git a/G-Earth/src/main/java/gearth/protocol/HConnection.java b/G-Earth/src/main/java/gearth/protocol/HConnection.java
index 511494d..aa917c9 100644
--- a/G-Earth/src/main/java/gearth/protocol/HConnection.java
+++ b/G-Earth/src/main/java/gearth/protocol/HConnection.java
@@ -1,10 +1,11 @@
package gearth.protocol;
import gearth.misc.listenerpattern.Observable;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.connection.HClient;
import gearth.protocol.connection.HProxy;
import gearth.protocol.connection.HState;
import gearth.protocol.connection.proxy.ProxyProvider;
-import gearth.protocol.connection.proxy.flash.FlashProxyProvider;
import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
import gearth.protocol.connection.proxy.unity.UnityProxyProvider;
@@ -137,16 +138,28 @@ public class HConnection {
public boolean sendToClientAsync(HPacket message) {
- if (proxy == null) {
- return false;
+ if (proxy == null) return false;
+
+ if (!message.isPacketComplete()) {
+ PacketInfoManager packetInfoManager = getPacketInfoManager();
+ message.completePacket(HMessage.Direction.TOCLIENT, packetInfoManager);
+
+ if (!message.isPacketComplete()) return false;
}
+
proxy.getAsyncPacketSender().sendToClientAsync(message);
return true;
}
public boolean sendToServerAsync(HPacket message) {
- if (proxy == null) {
- return false;
+ if (proxy == null) return false;
+
+ if (!message.isPacketComplete()) {
+ PacketInfoManager packetInfoManager = getPacketInfoManager();
+ message.completePacket(HMessage.Direction.TOSERVER, packetInfoManager);
+
+ if (!message.isPacketComplete()) return false;
}
+
proxy.getAsyncPacketSender().sendToServerAsync(message);
return true;
}
@@ -172,11 +185,25 @@ public class HConnection {
return proxy.getHotelVersion();
}
- public String getClientType() {
+ public String getClientIdentifier() {
if (proxy == null) {
return "";
}
- return proxy.getClientType();
+ return proxy.getClientIdentifier();
+ }
+
+ public HClient getClientType() {
+ if (proxy == null) {
+ return null;
+ }
+ return proxy.gethClient();
+ }
+
+ public PacketInfoManager getPacketInfoManager() {
+ if (proxy == null) {
+ return null;
+ }
+ return proxy.getPacketInfoManager();
}
public boolean isRawIpMode() {
diff --git a/G-Earth/src/main/java/gearth/protocol/HPacket.java b/G-Earth/src/main/java/gearth/protocol/HPacket.java
index 16b3205..9a2e65d 100644
--- a/G-Earth/src/main/java/gearth/protocol/HPacket.java
+++ b/G-Earth/src/main/java/gearth/protocol/HPacket.java
@@ -1,17 +1,17 @@
package gearth.protocol;
import gearth.misc.StringifyAble;
-import gearth.misc.harble_api.HarbleAPI;
-import gearth.misc.harble_api.HarbleAPIFetcher;
-import gearth.misc.packetrepresentation.InvalidPacketException;
-import gearth.misc.packetrepresentation.PacketStringUtils;
+import gearth.services.packet_info.PacketInfo;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.services.packetrepresentation.InvalidPacketException;
+import gearth.services.packetrepresentation.PacketStringUtils;
-import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.util.Arrays;
+import java.util.Optional;
public class HPacket implements StringifyAble {
@@ -19,6 +19,9 @@ public class HPacket implements StringifyAble {
private byte[] packetInBytes;
private int readIndex = 6;
+ // if identifier != null, this is a placeholder name for the type of packet, headerId will be "-1"
+ private String identifier = null;
+
public HPacket(byte[] packet) {
packetInBytes = packet.clone();
}
@@ -28,11 +31,11 @@ public class HPacket implements StringifyAble {
}
public HPacket(String packet) {
try {
- packetInBytes = PacketStringUtils.fromString(packet).packetInBytes;
+ HPacket packetFromString = PacketStringUtils.fromString(packet);
+ packetInBytes = packetFromString.packetInBytes;
+ identifier = packetFromString.identifier;
} catch (InvalidPacketException e) {
packetInBytes = new byte[0];
- // will be corrupted
- // e.printStackTrace();
}
}
public HPacket(int header) {
@@ -40,6 +43,7 @@ public class HPacket implements StringifyAble {
replaceShort(4, (short)header);
isEdited = false;
}
+
public HPacket(int header, byte[] bytes) {
this(header);
appendBytes(bytes);
@@ -53,14 +57,19 @@ public class HPacket implements StringifyAble {
*/
public HPacket(int header, Object... objects) throws InvalidParameterException {
this(header);
- for (int i = 0; i < objects.length; i++) {
- Object o = objects[i];
- appendObject(o);
- }
-
+ appendObjects(objects);
isEdited = false;
}
+ public HPacket(String identifier, Object... objects) throws InvalidParameterException {
+ packetInBytes = new byte[]{0,0,0,2,-1,-1};
+ this.identifier = identifier;
+ appendObjects(objects);
+ isEdited = false;
+ }
+
+
+
public String toString() {
return PacketStringUtils.toString(packetInBytes);
}
@@ -75,6 +84,46 @@ public class HPacket implements StringifyAble {
return 2;
}
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public void completePacket(HMessage.Direction direction, PacketInfoManager packetInfoManager) {
+ if (isCorrupted() || identifier == null) return;
+
+ PacketInfo packetInfo = packetInfoManager.getPacketInfoFromName(direction, identifier);
+ if (packetInfo == null) {
+ packetInfo = packetInfoManager.getPacketInfoFromHash(direction, identifier);
+ if (packetInfo == null) return;
+ }
+
+ boolean wasEdited = isEdited;
+ replaceShort(4, (short)(packetInfo.getHeaderId()));
+ identifier = null;
+
+ isEdited = wasEdited;
+ }
+
+ public boolean canComplete(HMessage.Direction direction, PacketInfoManager packetInfoManager) {
+ if (isCorrupted() || identifier == null) return false;
+
+ PacketInfo packetInfo = packetInfoManager.getPacketInfoFromName(direction, identifier);
+ if (packetInfo == null) {
+ packetInfo = packetInfoManager.getPacketInfoFromHash(direction, identifier);
+ return packetInfo != null;
+ }
+
+ return true;
+ }
+
+ public boolean isPacketComplete() {
+ return identifier == null;
+ }
+
public byte[] toBytes() {
return packetInBytes;
}
@@ -532,6 +581,14 @@ public class HPacket implements StringifyAble {
return appendLongString(s, StandardCharsets.ISO_8859_1);
}
+ public HPacket appendObjects(Object... objects) {
+ for (Object object : objects) {
+ appendObject(object);
+ }
+
+ return this;
+ }
+
public HPacket appendObject(Object o) throws InvalidParameterException {
isEdited = true;
@@ -580,45 +637,52 @@ public class HPacket implements StringifyAble {
isEdited = edited;
}
- private String getHarbleStructure(HMessage.Direction direction) {
- HarbleAPI.HarbleMessage msg;
- if (HarbleAPIFetcher.HARBLEAPI != null &&
- ((msg = HarbleAPIFetcher.HARBLEAPI.getHarbleMessageFromHeaderId(direction, headerId())) != null)) {
- if (msg.getStructure() != null && structureEquals(msg.getStructure())) {
- return msg.getStructure();
- }
- }
+ private PacketInfo getPacketInfo(HMessage.Direction direction, PacketInfoManager packetInfoManager) {
+ if (packetInfoManager == null) return null;
- return null;
+ // prefer packetinfo with structure information (not available in at time of writing)
+ Optional packetInfoMaybe = packetInfoManager.getAllPacketInfoFromHeaderId(direction, headerId())
+ .stream().filter(packetInfo -> packetInfo.getStructure() != null).findFirst();
+ return packetInfoMaybe.orElseGet(() -> packetInfoManager.getPacketInfoFromHeaderId(direction, headerId()));
}
- public String toExpression(HMessage.Direction direction) {
+ public String toExpression(HMessage.Direction direction, PacketInfoManager packetInfoManager, boolean removeShuffle) {
if (isCorrupted()) return "";
- String structure = getHarbleStructure(direction);
- if (structure != null) {
- return PacketStringUtils.toExpressionFromGivenStructure(this, structure);
+ PacketInfo packetInfo = getPacketInfo(direction, packetInfoManager);
+ if (packetInfo != null && packetInfo.getStructure() != null) {
+ return PacketStringUtils.toExpressionFromGivenStructure(this, packetInfo.getStructure(), removeShuffle ? packetInfo : null);
}
-
- return PacketStringUtils.predictedExpression(this);
+ return PacketStringUtils.predictedExpression(this, removeShuffle ? packetInfo : null);
}
/**
* returns "" if not found or not sure enough
*/
- public String toExpression() {
+ public String toExpression(PacketInfoManager packetInfoManager, boolean removeShuffle) {
if (isCorrupted()) return "";
- String structure1 = getHarbleStructure(HMessage.Direction.TOCLIENT);
- String structure2 = getHarbleStructure(HMessage.Direction.TOSERVER);
- if (structure1 != null && structure2 == null) {
- return PacketStringUtils.toExpressionFromGivenStructure(this, structure1);
+ PacketInfo maybe1 = getPacketInfo(HMessage.Direction.TOCLIENT, packetInfoManager);
+ PacketInfo maybe2 = getPacketInfo(HMessage.Direction.TOSERVER, packetInfoManager);
+
+ PacketInfo packetInfo = null;
+
+ if (maybe1 != null && maybe2 == null) {
+ packetInfo = maybe1;
}
- else if (structure1 == null && structure2 != null) {
- return PacketStringUtils.toExpressionFromGivenStructure(this, structure2);
+ else if (maybe1 == null && maybe2 != null) {
+ packetInfo = maybe2;
}
- return PacketStringUtils.predictedExpression(this);
+ if (packetInfo != null && packetInfo.getStructure() != null) {
+ return PacketStringUtils.toExpressionFromGivenStructure(this, packetInfo.getStructure(), removeShuffle ? packetInfo : null);
+ }
+ return PacketStringUtils.predictedExpression(this, removeShuffle ? packetInfo : null);
+ }
+
+ public String toExpression() {
+ if (isCorrupted()) return "";
+ return PacketStringUtils.predictedExpression(this, null);
}
@Override
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java b/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
index 530556d..13548a3 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
@@ -1,5 +1,6 @@
package gearth.protocol.connection;
+import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.packethandler.PacketHandler;
import java.net.ServerSocket;
@@ -21,7 +22,9 @@ public class HProxy {
private volatile PacketHandler outHandler = null; //connection with server (only initialized when verified habbo connection)
private volatile String hotelVersion = "";
- private volatile String clientType = "";
+ private volatile String clientIdentifier = "";
+ private volatile PacketInfoManager packetInfoManager = null;
+
private volatile AsyncPacketSender asyncPacketSender = null;
public HProxy(HClient hClient, String input_domain, String actual_domain, int actual_port, int intercept_port, String intercept_host) {
@@ -37,16 +40,17 @@ public class HProxy {
this.proxy_server = socket;
}
- public void verifyProxy(PacketHandler incomingHandler, PacketHandler outgoingHandler, String hotelVersion, String clientType) {
+ public void verifyProxy(PacketHandler incomingHandler, PacketHandler outgoingHandler, String hotelVersion, String clientIdentifier) {
this.inHandler = incomingHandler;
this.outHandler = outgoingHandler;
this.hotelVersion = hotelVersion;
- this.clientType = clientType;
+ this.clientIdentifier = clientIdentifier;
+ this.packetInfoManager = PacketInfoManager.fromHotelVersion(hotelVersion, hClient);
this.asyncPacketSender = new AsyncPacketSender(this);
}
- public String getClientType() {
- return clientType;
+ public String getClientIdentifier() {
+ return clientIdentifier;
}
public int getActual_port() {
@@ -92,4 +96,8 @@ public class HProxy {
public HClient gethClient() {
return hClient;
}
+
+ public PacketInfoManager getPacketInfoManager() {
+ return packetInfoManager;
+ }
}
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java
index b06c431..1a8ec33 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java
@@ -51,9 +51,9 @@ public abstract class FlashProxyProvider implements ProxyProvider {
Semaphore abort = new Semaphore(0);
- outgoingHandler.addOnDatastreamConfirmedListener((hotelVersion, clientType) -> {
+ outgoingHandler.addOnDatastreamConfirmedListener((hotelVersion, clientIdentifier) -> {
incomingHandler.setAsDataStream();
- proxy.verifyProxy(incomingHandler, outgoingHandler, hotelVersion, clientType);
+ proxy.verifyProxy(incomingHandler, outgoingHandler, hotelVersion, clientIdentifier);
proxySetter.setProxy(proxy);
datastream[0] = true;
abortSemaphore = abort;
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java
index c59ef92..36cd806 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java
@@ -59,12 +59,12 @@ public class UnityCommunicator {
if (maybe.getBytesLength() > 6 && maybe.headerId() == 4000) {
hProxy = new HProxy(HClient.UNITY, "", "", -1, -1, "");
String ignore = maybe.readString();
- String clientType = maybe.readString();
+ String clientIdentifier = maybe.readString();
hProxy.verifyProxy(
new UnityPacketHandler(hConnection.getExtensionHandler(), hConnection.getTrafficObservables(), session, HMessage.Direction.TOCLIENT),
new UnityPacketHandler(hConnection.getExtensionHandler(), hConnection.getTrafficObservables(), session, HMessage.Direction.TOSERVER),
revision,
- clientType
+ clientIdentifier
);
proxySetter.setProxy(hProxy);
stateSetter.setState(HState.CONNECTED);
diff --git a/G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
index 8801fef..7178b06 100644
--- a/G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
+++ b/G-Earth/src/main/java/gearth/protocol/memory/habboclient/windows/WindowsHabboClient.java
@@ -15,7 +15,7 @@ import java.net.URISyntaxException;
import java.util.*;
/**
- * Created by Jeunez on 27/06/2018.
+ * Created by Jonas on 27/06/2018.
*/
public class WindowsHabboClient extends HabboClient {
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java
index 6e13dab..f7ed253 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java
@@ -2,6 +2,6 @@ package gearth.protocol.packethandler.flash;
public interface OnDatastreamConfirmedListener {
- void confirm(String hotelVersion, String clientType);
+ void confirm(String hotelVersion, String clientIdentifier);
}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java
index a2775e6..84ddf7b 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java
@@ -26,9 +26,9 @@ public class OutgoingFlashPacketHandler extends FlashPacketHandler {
HPacket hpacket = new HPacket(buffer);
isDataStream = (hpacket.getBytesLength() > 6 && hpacket.length() < 100);
if (isDataStream) {
- String version = hpacket.readString();
- String clientType = hpacket.readString();
- datastreamConfirmedObservable.fireEvent(l -> l.confirm(version, clientType));
+ String hotelVersion = hpacket.readString();
+ String clientIdentifier = hpacket.readString();
+ datastreamConfirmedObservable.fireEvent(l -> l.confirm(hotelVersion, clientIdentifier));
}
}
}
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java b/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java
index 3d12d3a..5f26af8 100644
--- a/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java
@@ -1,7 +1,6 @@
package gearth.services.extensionhandler;
import gearth.Main;
-import gearth.misc.harble_api.HarbleAPIFetcher;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
@@ -12,6 +11,7 @@ import gearth.services.extensionhandler.extensions.GEarthExtension;
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducer;
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducerFactory;
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducerObserver;
+import gearth.services.packet_info.PacketInfoManager;
import javafx.util.Pair;
import java.io.IOException;
@@ -45,18 +45,17 @@ public class ExtensionHandler {
}
private void initialize() {
-
hConnection.getStateObservable().addListener((oldState, newState) -> {
if (newState == HState.CONNECTED) {
- HarbleAPIFetcher.fetch(hConnection.getHotelVersion(), hConnection.getClientType());
synchronized (gEarthExtensions) {
for (GEarthExtension extension : gEarthExtensions) {
extension.connectionStart(
hConnection.getDomain(),
hConnection.getServerPort(),
hConnection.getHotelVersion(),
+ hConnection.getClientIdentifier(),
hConnection.getClientType(),
- HarbleAPIFetcher.HARBLEAPI == null ? "null" : HarbleAPIFetcher.HARBLEAPI.getPath()
+ hConnection.getPacketInfoManager()
);
}
}
@@ -71,7 +70,7 @@ public class ExtensionHandler {
});
extensionProducers = ExtensionProducerFactory.getAll();
- extensionProducers.forEach(this::initializeExtensionProducer);
+ extensionProducers.forEach(extensionProducer -> extensionProducer.startProducing(createExtensionProducerObserver()));
}
@@ -174,8 +173,8 @@ public class ExtensionHandler {
- private void initializeExtensionProducer(ExtensionProducer producer) {
- producer.startProducing(new ExtensionProducerObserver() {
+ private ExtensionProducerObserver createExtensionProducerObserver() {
+ return new ExtensionProducerObserver() {
@Override
public void onExtensionProduced(GEarthExtension extension) {
synchronized (gEarthExtensions) {
@@ -221,7 +220,7 @@ public class ExtensionHandler {
try {
s = packet.toString();
if (packet.length() < 3000) {
- expression = packet.toExpression();
+ expression = packet.toExpression(hConnection.getPacketInfoManager(), true);
}
}
finally {
@@ -232,6 +231,13 @@ public class ExtensionHandler {
@Override
protected void stringToPacketRequest(String string) {
HPacket packet = new HPacket(string);
+ PacketInfoManager packetInfoManager = hConnection.getPacketInfoManager();
+ if (packet.canComplete(HMessage.Direction.TOCLIENT, packetInfoManager) && !packet.canComplete(HMessage.Direction.TOSERVER, packetInfoManager)) {
+ packet.completePacket(HMessage.Direction.TOCLIENT, packetInfoManager);
+ }
+ else if (!packet.canComplete(HMessage.Direction.TOCLIENT, packetInfoManager) && packet.canComplete(HMessage.Direction.TOSERVER, packetInfoManager)) {
+ packet.completePacket(HMessage.Direction.TOSERVER, packetInfoManager);
+ }
extension.stringToPacketResponse(packet);
}
};
@@ -244,8 +250,9 @@ public class ExtensionHandler {
hConnection.getDomain(),
hConnection.getServerPort(),
hConnection.getHotelVersion(),
+ hConnection.getClientIdentifier(),
hConnection.getClientType(),
- HarbleAPIFetcher.HARBLEAPI == null ? "null" : HarbleAPIFetcher.HARBLEAPI.getPath()
+ hConnection.getPacketInfoManager()
);
}
@@ -254,7 +261,7 @@ public class ExtensionHandler {
observable.fireEvent(l -> l.onExtensionConnect(extension));
}
- });
+ };
}
public List getExtensionProducers() {
@@ -264,5 +271,10 @@ public class ExtensionHandler {
return observable;
}
+ public void addExtensionProducer(ExtensionProducer producer) {
+ producer.startProducing(createExtensionProducerObserver());
+ extensionProducers.add(producer);
+ }
+
}
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/ExtensionType.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/ExtensionType.java
new file mode 100644
index 0000000..00d0358
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/ExtensionType.java
@@ -0,0 +1,6 @@
+package gearth.services.extensionhandler.extensions;
+
+public enum ExtensionType {
+ INTERNAL,
+ EXTERNAL
+}
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/GEarthExtension.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/GEarthExtension.java
index ce52885..a22d847 100644
--- a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/GEarthExtension.java
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/GEarthExtension.java
@@ -2,14 +2,14 @@ package gearth.services.extensionhandler.extensions;
import gearth.misc.listenerpattern.Observable;
import gearth.misc.listenerpattern.SynchronizedObservable;
+import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
+import gearth.protocol.connection.HClient;
import gearth.services.extensionhandler.extensions.listeners.OmRemoveClickListener;
import gearth.services.extensionhandler.extensions.listeners.OnClickListener;
import gearth.services.extensionhandler.extensions.listeners.OnDeleteListener;
-import java.util.function.Consumer;
-
public abstract class GEarthExtension {
@@ -38,7 +38,7 @@ public abstract class GEarthExtension {
public abstract void doubleclick();
public abstract void packetIntercept(HMessage hMessage);
public abstract void provideFlags(String[] flags);
- public abstract void connectionStart(String host, int port, String hotelVersion, String clientType, String harbleMessagesPath);
+ public abstract void connectionStart(String host, int port, String hotelVersion, String clientIdentifier, HClient clientType, PacketInfoManager packetInfoManager);
public abstract void connectionEnd();
public abstract void init();
public abstract void close();
@@ -51,7 +51,6 @@ public abstract class GEarthExtension {
// ----------------- listen to the extension ---------------------
-
protected final Observable extensionObservable = new SynchronizedObservable<>();
public Observable getExtensionObservable() {
return extensionObservable;
@@ -121,4 +120,7 @@ public abstract class GEarthExtension {
}
// ----------------------------------------------------------------------------------------
+
+
+ public abstract ExtensionType extensionType();
}
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/extensionproducers/ExtensionProducerFactory.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/extensionproducers/ExtensionProducerFactory.java
index d02b910..40c0b83 100644
--- a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/extensionproducers/ExtensionProducerFactory.java
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/extensionproducers/ExtensionProducerFactory.java
@@ -3,6 +3,7 @@ package gearth.services.extensionhandler.extensions.extensionproducers;
import gearth.services.extensionhandler.extensions.implementations.network.NetworkExtensionsProducer;
import gearth.services.extensionhandler.extensions.implementations.simple.SimpleExtensionProducer;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -10,10 +11,11 @@ public class ExtensionProducerFactory {
// returns one of every ExtensionProducer class we have created, to support all types of extensions
public static List getAll() {
- return Arrays.asList(
- new NetworkExtensionsProducer(),
- new SimpleExtensionProducer()
- );
+ List all = new ArrayList<>();
+ all.add(new NetworkExtensionsProducer());
+ all.add(new SimpleExtensionProducer());
+
+ return all;
}
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/NetworkExtension.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/NetworkExtension.java
index 707a3d2..6d6eaf4 100644
--- a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/NetworkExtension.java
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/network/NetworkExtension.java
@@ -1,6 +1,9 @@
package gearth.services.extensionhandler.extensions.implementations.network;
+import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.HMessage;
+import gearth.protocol.connection.HClient;
+import gearth.services.extensionhandler.extensions.ExtensionType;
import gearth.services.extensionhandler.extensions.GEarthExtension;
import gearth.protocol.HPacket;
@@ -190,15 +193,16 @@ public class NetworkExtension extends GEarthExtension {
}
@Override
- public void connectionStart(String host, int port, String hotelVersion, String clientType, String harbleMessagesPath) {
- sendMessage(
- new HPacket(NetworkExtensionInfo.OUTGOING_MESSAGES_IDS.CONNECTIONSTART)
- .appendString(host)
- .appendInt(port)
- .appendString(hotelVersion)
- .appendString(harbleMessagesPath)
- .appendString(clientType)
- );
+ public void connectionStart(String host, int port, String hotelVersion, String clientIdentifier, HClient clientType, PacketInfoManager packetInfoManager) {
+ HPacket connectionStartPacket = new HPacket(NetworkExtensionInfo.OUTGOING_MESSAGES_IDS.CONNECTIONSTART)
+ .appendString(host)
+ .appendInt(port)
+ .appendString(hotelVersion)
+ .appendString(clientIdentifier)
+ .appendString(clientType.name());
+
+ packetInfoManager.appendToPacket(connectionStartPacket);
+ sendMessage(connectionStartPacket);
}
@Override
@@ -236,4 +240,9 @@ public class NetworkExtension extends GEarthExtension {
packet.appendLongString(packetFromString.stringify());
sendMessage(packet);
}
+
+ @Override
+ public ExtensionType extensionType() {
+ return ExtensionType.EXTERNAL;
+ }
}
\ No newline at end of file
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/ExampleExtension.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/ExampleExtension.java
index 909deae..a33bf9b 100644
--- a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/ExampleExtension.java
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/ExampleExtension.java
@@ -1,7 +1,10 @@
package gearth.services.extensionhandler.extensions.implementations.simple;
+import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
+import gearth.protocol.connection.HClient;
+import gearth.services.extensionhandler.extensions.ExtensionType;
import gearth.services.extensionhandler.extensions.GEarthExtension;
public class ExampleExtension extends GEarthExtension {
@@ -83,7 +86,7 @@ public class ExampleExtension extends GEarthExtension {
}
@Override
- public void connectionStart(String host, int port, String hotelVersion, String clientType, String harbleMessagesPath) {
+ public void connectionStart(String host, int port, String hotelVersion, String clientIdentifier, HClient clientType, PacketInfoManager packetInfoManager) {
// a new habbo client has connected
System.out.println("Connected to " + host);
}
@@ -120,4 +123,9 @@ public class ExampleExtension extends GEarthExtension {
public void stringToPacketResponse(HPacket packet) {
}
+
+ @Override
+ public ExtensionType extensionType() {
+ return ExtensionType.INTERNAL;
+ }
}
diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/SimpleExtensionProducer.java b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/SimpleExtensionProducer.java
index 105b907..25b753c 100644
--- a/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/SimpleExtensionProducer.java
+++ b/G-Earth/src/main/java/gearth/services/extensionhandler/extensions/implementations/simple/SimpleExtensionProducer.java
@@ -1,7 +1,10 @@
package gearth.services.extensionhandler.extensions.implementations.simple;
+import gearth.extensions.InternalExtensionFormBuilder;
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducer;
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducerObserver;
+import gearth.services.internal_extensions.blockreplacepackets.BlockAndReplacePackets;
+import gearth.services.internal_extensions.packetinfoexplorer.PacketInfoExplorer;
public class SimpleExtensionProducer implements ExtensionProducer {
@@ -9,7 +12,12 @@ public class SimpleExtensionProducer implements ExtensionProducer {
public void startProducing(ExtensionProducerObserver observer) {
// uncomment the next line if you want to see an embedded example extension in G-Earth
- // observer.onExtensionConnect(new ExampleExtension());
+// observer.onExtensionProduced(new ExampleExtension());
+ new InternalExtensionFormBuilder()
+ .launch(BlockAndReplacePackets.class, observer);
+
+ new InternalExtensionFormBuilder()
+ .launch(PacketInfoExplorer.class, observer);
}
}
diff --git a/G-Earth/src/main/java/gearth/services/gpython/GPythonVersionUtils.java b/G-Earth/src/main/java/gearth/services/gpython/GPythonVersionUtils.java
index 34e2be0..0c839ea 100644
--- a/G-Earth/src/main/java/gearth/services/gpython/GPythonVersionUtils.java
+++ b/G-Earth/src/main/java/gearth/services/gpython/GPythonVersionUtils.java
@@ -10,7 +10,7 @@ import java.util.List;
public class GPythonVersionUtils {
- private static final String MIN_GPYTHON_VERSION = "0.1.3";
+ private static final String MIN_GPYTHON_VERSION = "0.1.4";
private static final String MIN_PYTHON_VERSION = "3.2";
// returns null if python not installed
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/BlockAndReplacePackets.java
similarity index 77%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/BlockAndReplacePackets.java
index ad3d6ff..6838aad 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/BlockAndReplacePackets.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/BlockAndReplacePackets.java
@@ -1,10 +1,14 @@
-package extensions.blockreplacepackets;
+package gearth.services.internal_extensions.blockreplacepackets;
-import extensions.blockreplacepackets.rules.BlockReplaceRule;
-import extensions.blockreplacepackets.rules.RuleFactory;
-import gearth.extensions.Extension;
+import gearth.Main;
+import gearth.extensions.ExtensionForm;
+import gearth.extensions.ExtensionInfo;
+import gearth.services.packet_info.PacketInfo;
+import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
+import gearth.services.internal_extensions.blockreplacepackets.rules.BlockReplaceRule;
+import gearth.services.internal_extensions.blockreplacepackets.rules.RuleFactory;
import gearth.ui.GEarthController;
import javafx.application.Platform;
import javafx.event.ActionEvent;
@@ -15,11 +19,10 @@ import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
+import javafx.scene.image.Image;
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;
@@ -32,7 +35,7 @@ import java.util.List;
@ExtensionInfo(
Title = "G-Manipulate",
Description = "Block &/ replace packets",
- Version = "0.1",
+ Version = "0.2",
Author = "sirjonasxx"
)
public class BlockAndReplacePackets extends ExtensionForm {
@@ -48,9 +51,11 @@ public class BlockAndReplacePackets extends ExtensionForm {
List rules = new ArrayList<>();
- public static void main(String[] args) {
- runExtensionForm(args, BlockAndReplacePackets.class);
- }
+ private PacketInfoManager packetInfoManager = PacketInfoManager.EMPTY;
+
+// public static void main(String[] args) {
+// runExtensionForm(args, BlockAndReplacePackets.class);
+// }
//initialize javaFX elements
public void initialize() {
@@ -70,6 +75,26 @@ public class BlockAndReplacePackets extends ExtensionForm {
}
+ private String getVal() {
+ String val = txt_value.getText();
+ String type = cmb_type.getSelectionModel().getSelectedItem();
+ String side = cmb_side.getSelectionModel().getSelectedItem();
+
+ if (type.endsWith("packet")) {
+ HMessage.Direction dir = side.equals("Outgoing") ? HMessage.Direction.TOSERVER : HMessage.Direction.TOCLIENT;
+ PacketInfo fromName = packetInfoManager.getPacketInfoFromName(dir, val);
+ PacketInfo fromHash = packetInfoManager.getPacketInfoFromHash(dir, val);
+ if (fromName != null) {
+ val = fromName.getHeaderId() +"";
+ }
+ else if (fromHash != null) {
+ val = fromHash.getHeaderId() +"";
+ }
+ }
+
+ return val;
+ }
+
private void refreshOptions() {
txt_replacement.setDisable(cmb_type.getSelectionModel().getSelectedItem().startsWith("Block"));
if (cmb_side.getItems().size() == 2 && !cmb_type.getSelectionModel().getSelectedItem().endsWith("packet")) {
@@ -83,7 +108,7 @@ public class BlockAndReplacePackets extends ExtensionForm {
}
boolean isValid = false;
- String val = txt_value.getText();
+ String val = getVal();
String repl = txt_replacement.getText();
String type = cmb_type.getSelectionModel().getSelectedItem();
String side = cmb_side.getSelectionModel().getSelectedItem();
@@ -154,7 +179,7 @@ public class BlockAndReplacePackets extends ExtensionForm {
if (val.equals("")) {
if (spl[1].equals("packet")) {
- txt_value.setPromptText("Enter the headerID");
+ txt_value.setPromptText("Enter headerID/name");
}
else if (spl[1].equals("integer")) {
txt_value.setPromptText("Enter an integer");
@@ -177,7 +202,7 @@ public class BlockAndReplacePackets extends ExtensionForm {
@Override
protected void initExtension() {
- Extension.MessageListener messageListener = message -> {
+ MessageListener messageListener = message -> {
for (BlockReplaceRule rule : rules) {
rule.appendRuleToMessage(message);
}
@@ -185,6 +210,10 @@ public class BlockAndReplacePackets extends ExtensionForm {
intercept(HMessage.Direction.TOSERVER, messageListener);
intercept(HMessage.Direction.TOCLIENT, messageListener);
+
+ onConnect((host, port, hotelversion, clientIdentifier, clientType, packetInfoManager) -> {
+ this.packetInfoManager = packetInfoManager;
+ });
}
@Override
@@ -196,6 +225,7 @@ public class BlockAndReplacePackets extends ExtensionForm {
primaryStage.setScene(new Scene(root));
primaryStage.setResizable(false);
primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("/gearth/ui/bootstrap3.css").toExternalForm());
+ primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("G-EarthLogoSmaller.png")));
return loader.getController();
}
@@ -206,7 +236,8 @@ public class BlockAndReplacePackets extends ExtensionForm {
}
public void click_btnAddRule(ActionEvent actionEvent) {
- BlockReplaceRule rule = RuleFactory.getRule(cmb_type.getSelectionModel().getSelectedItem(), cmb_side.getSelectionModel().getSelectedItem(), txt_value.getText(), txt_replacement.getText());
+ BlockReplaceRule rule = RuleFactory.getRule(cmb_type.getSelectionModel().getSelectedItem(),
+ cmb_side.getSelectionModel().getSelectedItem(), getVal(), txt_replacement.getText(), packetInfoManager);
rules.add(rule);
rule.onDelete(observable -> rules.remove(rule));
new RuleContainer(rule, vbox);
@@ -215,6 +246,11 @@ public class BlockAndReplacePackets extends ExtensionForm {
clearInput();
}
+ @Override
+ protected boolean canLeave() {
+ return false;
+ }
+
@Override
protected boolean canDelete() {
return false;
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/RuleContainer.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/RuleContainer.java
similarity index 93%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/RuleContainer.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/RuleContainer.java
index c72ee00..4539d53 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/RuleContainer.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/RuleContainer.java
@@ -1,6 +1,6 @@
-package extensions.blockreplacepackets;
+package gearth.services.internal_extensions.blockreplacepackets;
-import extensions.blockreplacepackets.rules.BlockReplaceRule;
+import gearth.services.internal_extensions.blockreplacepackets.rules.BlockReplaceRule;
import gearth.ui.buttons.DeleteButton;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@@ -13,7 +13,7 @@ import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
/**
- * Created by Jeunez on 6/11/2018.
+ * Created by Jonas on 6/11/2018.
*/
public class RuleContainer extends GridPane {
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockPacketRule.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/BlockPacketRule.java
similarity index 94%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockPacketRule.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/BlockPacketRule.java
index d80c675..a8e22df 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockPacketRule.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/BlockPacketRule.java
@@ -1,4 +1,4 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockReplaceRule.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/BlockReplaceRule.java
similarity index 93%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockReplaceRule.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/BlockReplaceRule.java
index d1cc521..621cf0a 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/BlockReplaceRule.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/BlockReplaceRule.java
@@ -1,4 +1,4 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
import javafx.beans.InvalidationListener;
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceIntegerRule.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
similarity index 94%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
index f543461..d5141ee 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceIntegerRule.java
@@ -1,4 +1,4 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplacePacketRule.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplacePacketRule.java
similarity index 92%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplacePacketRule.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplacePacketRule.java
index c6bfa0d..6134234 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplacePacketRule.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplacePacketRule.java
@@ -1,10 +1,10 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
/**
- * Created by Jeunez on 6/11/2018.
+ * Created by Jonas on 6/11/2018.
*/
public class ReplacePacketRule extends BlockReplaceRule {
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceStringRule.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceStringRule.java
similarity index 94%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceStringRule.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceStringRule.java
index fd20820..5449370 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceStringRule.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceStringRule.java
@@ -1,4 +1,4 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceSubstringRule.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
similarity index 94%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
index 9e56286..dbb58be 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/ReplaceSubstringRule.java
@@ -1,4 +1,4 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
import gearth.protocol.HMessage;
diff --git a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/RuleFactory.java b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/RuleFactory.java
similarity index 72%
rename from Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/RuleFactory.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/RuleFactory.java
index ef99e03..a6dc50f 100644
--- a/Extensions/BlockReplacePackets/src/main/java/extensions/blockreplacepackets/rules/RuleFactory.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/blockreplacepackets/rules/RuleFactory.java
@@ -1,5 +1,7 @@
-package extensions.blockreplacepackets.rules;
+package gearth.services.internal_extensions.blockreplacepackets.rules;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
/**
@@ -7,7 +9,7 @@ import gearth.protocol.HPacket;
*/
public class RuleFactory {
- public static BlockReplaceRule getRule(String type, String side, String value, String replacement) {
+ public static BlockReplaceRule getRule(String type, String side, String value, String replacement, PacketInfoManager packetInfoManager) {
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());
@@ -24,7 +26,11 @@ public class RuleFactory {
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));
+ HPacket packet = new HPacket(replacement);
+ if (!packet.isPacketComplete()) {
+ packet.completePacket(rSide == BlockReplaceRule.Side.INCOMING ? HMessage.Direction.TOCLIENT : HMessage.Direction.TOSERVER, packetInfoManager);
+ }
+ return new ReplacePacketRule(rSide, Integer.parseInt(value), packet);
}
if (rType == BlockReplaceRule.Type.STRING) {
return new ReplaceStringRule(rSide, value, replacement);
diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/packetinfoexplorer/PacketInfoExplorer.java b/G-Earth/src/main/java/gearth/services/internal_extensions/packetinfoexplorer/PacketInfoExplorer.java
new file mode 100644
index 0000000..2795abe
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/packetinfoexplorer/PacketInfoExplorer.java
@@ -0,0 +1,189 @@
+package gearth.services.internal_extensions.packetinfoexplorer;
+
+import gearth.Main;
+import gearth.extensions.ExtensionForm;
+import gearth.extensions.ExtensionInfo;
+import gearth.services.packet_info.PacketInfo;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.HMessage;
+import gearth.ui.GEarthController;
+import javafx.application.Platform;
+import javafx.beans.InvalidationListener;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.control.TextField;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.image.Image;
+import javafx.scene.layout.GridPane;
+import javafx.stage.Stage;
+
+import java.util.*;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@ExtensionInfo(
+ Title = "Packet Info",
+ Description = "Packet info explorer",
+ Version = "0.1",
+ Author = "sirjonasxx"
+)
+public class PacketInfoExplorer extends ExtensionForm {
+ public TextField txt_filterHeaderId;
+ public TextField txt_filterNameHash;
+ public GridPane source_grid;
+ public CheckBox chk_toClient;
+ public CheckBox chk_toServer;
+
+ private Map chk_sources = new HashMap<>();
+
+ private List packetInfoList = new ArrayList<>();
+
+ private TableView tableView;
+ public GridPane grid;
+
+ @Override
+ public ExtensionForm launchForm(Stage primaryStage) throws Exception {
+ FXMLLoader loader = new FXMLLoader(PacketInfoExplorer.class.getResource("PacketInfoExplorer.fxml"));
+ Parent root = loader.load();
+
+ primaryStage.setTitle("Packet info explorer");
+ primaryStage.setScene(new Scene(root));
+ primaryStage.setMinWidth(430);
+ primaryStage.setMinHeight(260);
+ primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("/gearth/ui/bootstrap3.css").toExternalForm());
+ primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("G-EarthLogoSmaller.png")));
+
+ return loader.getController();
+ }
+
+ public void initialize() {
+ Platform.runLater( () -> grid.requestFocus() );
+
+ tableView = new TableView<>();
+ tableView.setTableMenuButtonVisible(true);
+ tableView.setStyle("-fx-focus-color: white;");
+
+ tableView.focusedProperty().addListener(observable -> {
+ if (tableView.isFocused()) {
+ grid.requestFocus();
+ }
+ });
+
+ TableColumn headerIdColumn = new TableColumn<>("Header ID");
+ headerIdColumn.setCellValueFactory(new PropertyValueFactory<>("headerId"));
+
+ TableColumn directionColumn = new TableColumn<>("Direction");
+ directionColumn.setCellValueFactory(new PropertyValueFactory<>("destination"));
+ directionColumn.setPrefWidth(96);
+
+ TableColumn packetNameColumn = new TableColumn<>("Name");
+ packetNameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
+ packetNameColumn.setPrefWidth(220);
+
+ TableColumn packetHashColumn = new TableColumn<>("Hash");
+ packetHashColumn.setVisible(false);
+ packetHashColumn.setCellValueFactory(new PropertyValueFactory<>("hash"));
+ packetHashColumn.setPrefWidth(220);
+
+ TableColumn structureColumn = new TableColumn<>("Structure");
+ structureColumn.setCellValueFactory(new PropertyValueFactory<>("structure"));
+ structureColumn.setPrefWidth(115);
+
+ TableColumn sourceColumn = new TableColumn<>("Source");
+ sourceColumn.setCellValueFactory(new PropertyValueFactory<>("source"));
+
+ tableView.getColumns().addAll(Arrays.asList(headerIdColumn, directionColumn, packetNameColumn,
+ packetHashColumn, structureColumn, sourceColumn));
+
+ grid.add(tableView, 0, 1);
+
+ InvalidationListener filterValues = observable -> updateTableValues();
+ txt_filterHeaderId.textProperty().addListener(filterValues);
+ txt_filterNameHash.textProperty().addListener(filterValues);
+ chk_toClient.selectedProperty().addListener(filterValues);
+ chk_toClient.selectedProperty().addListener(filterValues);
+ }
+
+ @Override
+ protected void initExtension() {
+ onConnect((host, port, hotelversion, clientIdentifier, clientType, packetInfoManager) -> {
+ setPacketInfoManager(packetInfoManager);
+ });
+ }
+
+ @Override
+ protected void onEndConnection() {
+ setPacketInfoManager(PacketInfoManager.EMPTY);
+ }
+
+ private void setPacketInfoManager(PacketInfoManager packetInfoManager) {
+ packetInfoList = packetInfoManager.getPacketInfoList();
+ packetInfoList.sort(Comparator.comparingInt(PacketInfo::getHeaderId));
+
+ Platform.runLater(() -> {
+ source_grid.getChildren().clear();
+ chk_sources.clear();
+ for (PacketInfo packetInfo : packetInfoList) {
+ if (!chk_sources.containsKey(packetInfo.getSource())) {
+ CheckBox checkBox = new CheckBox(packetInfo.getSource());
+ checkBox.setSelected(true);
+ checkBox.selectedProperty().addListener(observable -> updateTableValues());
+ source_grid.add(checkBox, 0, chk_sources.size());
+ chk_sources.put(packetInfo.getSource(), checkBox);
+ }
+ }
+
+ primaryStage.setTitle("Packet info explorer | " + packetInfoList.size() + " packets");
+
+ updateTableValues();
+ });
+
+ }
+
+ private void updateTableValues() {
+ tableView.getItems().clear();
+
+ IntegerProperty doHeaderIdFilter = new SimpleIntegerProperty(-1);
+ if (!txt_filterHeaderId.getText().equals("")) {
+ try {
+ doHeaderIdFilter.setValue(Integer.parseInt(txt_filterHeaderId.getText()));
+ }
+ catch (Exception ignore) {}
+ }
+
+
+ List allPacketInfos = packetInfoList.stream()
+ .filter(packetInfo -> {
+ if (doHeaderIdFilter.get() != -1 && packetInfo.getHeaderId() != doHeaderIdFilter.get()) return false;
+ String filterNameHashLower = txt_filterNameHash.getText().toLowerCase();
+ if (!filterNameHashLower.equals("")
+ && (packetInfo.getName() == null || !packetInfo.getName().toLowerCase().contains(filterNameHashLower))
+ && (packetInfo.getHash() == null || !packetInfo.getHash().toLowerCase().contains(filterNameHashLower))) {
+ return false;
+ }
+ if ((!chk_toClient.isSelected() && packetInfo.getDestination() == HMessage.Direction.TOCLIENT)
+ || (!chk_toServer.isSelected() && packetInfo.getDestination() == HMessage.Direction.TOSERVER)) {
+ return false;
+ }
+ if (!chk_sources.get(packetInfo.getSource()).isSelected()) return false;
+ return true;
+ }).collect(Collectors.toList());
+
+
+ tableView.getItems().addAll(allPacketInfos);
+ }
+
+ @Override
+ protected boolean canLeave() {
+ return false;
+ }
+
+ @Override
+ protected boolean canDelete() {
+ return false;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/ui/logger/loggerdisplays/uilogger/Element.java b/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/Element.java
similarity index 80%
rename from G-Earth/src/main/java/gearth/ui/logger/loggerdisplays/uilogger/Element.java
rename to G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/Element.java
index 7c6d0d1..7a8169a 100644
--- a/G-Earth/src/main/java/gearth/ui/logger/loggerdisplays/uilogger/Element.java
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/Element.java
@@ -1,4 +1,4 @@
-package gearth.ui.logger.loggerdisplays.uilogger;
+package gearth.services.internal_extensions.uilogger;
/**
* Created by Jonas on 17/11/2018.
diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/UiLogger.java b/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/UiLogger.java
new file mode 100644
index 0000000..fa594f7
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/UiLogger.java
@@ -0,0 +1,108 @@
+package gearth.services.internal_extensions.uilogger;
+
+import gearth.extensions.ExtensionForm;
+import gearth.extensions.ExtensionInfo;
+import gearth.services.packet_info.PacketInfoManager;
+import gearth.protocol.HConnection;
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+import gearth.ui.logger.loggerdisplays.PacketLogger;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+@ExtensionInfo(
+ Title = "Packet Logger",
+ Description = "",
+ Version = "1.0",
+ Author = "sirjonasxx & Scott"
+)
+public class UiLogger extends ExtensionForm implements PacketLogger {
+ private UiLoggerController controller = null;
+
+ @Override
+ public void start(HConnection hConnection) {
+// // don't let the user close this window on their own
+// stage.setOnCloseRequest(Event::consume);
+
+// primaryStage.show();
+ }
+
+ @Override
+ public void stop() {
+// primaryStage.hide();
+// if (stage != null)
+// stage.close();
+ }
+
+ @Override
+ public void appendSplitLine() {
+ // don't use this, we can't discern incoming/outgoing
+ //Platform.runLater(() -> controller.appendSplitLine());
+ }
+
+ @Override
+ protected void initExtension() {
+ onConnect((host, port, hotelversion, clientIdentifier, clientType, packetInfoManager) -> {
+ controller.setPacketInfoManager(packetInfoManager);
+ controller.onConnect();
+ });
+ }
+
+ @Override
+ protected void onEndConnection() {
+ controller.onDisconnect();
+ controller.setPacketInfoManager(PacketInfoManager.EMPTY);
+ }
+
+ @Override
+ public ExtensionForm launchForm(Stage stage) throws Exception {
+ FXMLLoader loader = new FXMLLoader(UiLogger.class.getResource("UiLogger.fxml"));
+
+ Parent root = loader.load();
+ stage.setTitle("G-Earth | Packet Logger");
+ stage.initModality(Modality.NONE);
+ stage.getIcons().add(new Image(getClass().getResourceAsStream("/gearth/G-EarthLogoSmaller.png")));
+
+ Scene scene = new Scene(root);
+ scene.getStylesheets().add("/gearth/ui/bootstrap3.css");
+ scene.getStylesheets().add("/gearth/services/internal_extensions/uilogger/logger.css");
+ controller = loader.getController();
+ controller.setStage(stage);
+
+ stage.setScene(scene);
+ return this;
+ }
+
+ private class Elem {
+ HPacket packet;
+ int types;
+ Elem(HPacket packet, int types) {
+ this.packet = packet;
+ this.types = types;
+ }
+ }
+
+ @Override
+ public void appendMessage(HPacket packet, int types) {
+ controller.appendMessage(packet, types);
+ }
+
+ @Override
+ public void appendStructure(HPacket packet, HMessage.Direction direction) {
+
+ }
+
+ @Override
+ protected boolean canLeave() {
+ return false;
+ }
+
+ @Override
+ protected boolean canDelete() {
+ return false;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/UiLoggerController.java b/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/UiLoggerController.java
new file mode 100644
index 0000000..6321745
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/internal_extensions/uilogger/UiLoggerController.java
@@ -0,0 +1,400 @@
+package gearth.services.internal_extensions.uilogger;
+
+ import gearth.misc.Cacher;
+ import gearth.services.packet_info.PacketInfo;
+ import gearth.services.packet_info.PacketInfoManager;
+ import gearth.protocol.HMessage;
+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.control.MenuItem;
+ import javafx.scene.control.RadioMenuItem;
+ import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.FlowPane;
+ import javafx.stage.FileChooser;
+ import javafx.stage.Stage;
+import org.fxmisc.flowless.VirtualizedScrollPane;
+import org.fxmisc.richtext.StyleClassedTextArea;
+import org.fxmisc.richtext.model.StyleSpansBuilder;
+
+ import java.io.BufferedWriter;
+ import java.io.File;
+ import java.io.FileWriter;
+ import java.io.IOException;
+ import java.net.URL;
+import java.util.*;
+ import java.util.stream.Collectors;
+
+public class UiLoggerController implements Initializable {
+
+ private static final String LOGGER_SETTINGS_CACHE = "LOGGER_SETTINGS";
+
+ 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;
+ public CheckMenuItem chkMessageName;
+ public CheckMenuItem chkMessageHash;
+ public Label lblPacketInfo;
+ public CheckMenuItem chkUseNewStructures;
+ public CheckMenuItem chkAlwaysOnTop;
+
+ public CheckMenuItem chkOpenOnConnect;
+ public CheckMenuItem chkResetOnConnect;
+ public CheckMenuItem chkHideOnDisconnect;
+ public CheckMenuItem chkResetOnDisconnect;
+
+ private final static int FILTER_AMOUNT_THRESHOLD_L = 15;
+ private final static int FILTER_AMOUNT_THRESHOLD_M = 9;
+ private final static int FILTER_AMOUNT_THRESHOLD_H = 4;
+ private final static int FILTER_AMOUNT_THRESHOLD_U = 2;
+ private final static int FILTER_TIME_THRESHOLD = 5000;
+
+ public RadioMenuItem chkAntiSpam_none;
+ public RadioMenuItem chkAntiSpam_low;
+ public RadioMenuItem chkAntiSpam_medium;
+ public RadioMenuItem chkAntiSpam_high;
+ public RadioMenuItem chkAntiSpam_ultra;
+ public Label lblFiltered;
+
+ private Map> filterTimestamps = new HashMap<>();
+
+ private StyleClassedTextArea area;
+
+ private Stage stage;
+ private PacketInfoManager packetInfoManager = null;
+
+ private int filteredAmount = 0;
+
+ private volatile boolean initialized = false;
+ private final List appendLater = new ArrayList<>();
+
+ private List