Merge remote-tracking branch 'origin/master' into windowsSupport
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
.idea/
|
.idea/
|
||||||
out/
|
out/
|
||||||
G-Earth2.iml
|
G-Earth2.iml
|
||||||
|
Extensions/
|
||||||
|
3
src/META-INF/MANIFEST.MF
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: main.extensions.examples.adminonconnect.AdminOnConnect
|
||||||
|
|
BIN
src/json-simple-1.1.1.jar
Normal file
@ -1,6 +1,7 @@
|
|||||||
package main;
|
package main;
|
||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
@ -17,7 +18,6 @@ public class Main extends Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception{
|
public void start(Stage primaryStage) throws Exception{
|
||||||
|
|
||||||
FXMLLoader loader = new FXMLLoader(GEarthController.class.getResource("G-Earth.fxml"));
|
FXMLLoader loader = new FXMLLoader(GEarthController.class.getResource("G-Earth.fxml"));
|
||||||
Parent root = loader.load();
|
Parent root = loader.load();
|
||||||
|
|
||||||
@ -29,11 +29,11 @@ public class Main extends Application {
|
|||||||
primaryStage.setTitle("G-Earth");
|
primaryStage.setTitle("G-Earth");
|
||||||
primaryStage.setScene(new Scene(root, 620, 295));
|
primaryStage.setScene(new Scene(root, 620, 295));
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
|
|
||||||
primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("bootstrap3.css").toExternalForm());
|
primaryStage.getScene().getStylesheets().add(GEarthController.class.getResource("bootstrap3.css").toExternalForm());
|
||||||
|
|
||||||
primaryStage.setOnCloseRequest( event -> {
|
primaryStage.setOnCloseRequest( event -> {
|
||||||
companion.abort();
|
companion.abort();
|
||||||
|
Platform.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,7 @@ import main.protocol.HMessage;
|
|||||||
import main.protocol.HPacket;
|
import main.protocol.HPacket;
|
||||||
import main.ui.extensions.Extensions;
|
import main.ui.extensions.Extensions;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -26,14 +23,29 @@ public abstract class Extension {
|
|||||||
void act(String[] args);
|
void act(String[] args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static final boolean CANLEAVE = true; // can you disconnect the ext
|
||||||
|
protected static final boolean CANDELETE = true; // can you delete the ext (will be false for some built-in extensions)
|
||||||
|
|
||||||
|
private String[] args;
|
||||||
|
private boolean isCorrupted = false;
|
||||||
private static final String[] PORT_FLAG = {"--port", "-p"};
|
private static final String[] PORT_FLAG = {"--port", "-p"};
|
||||||
|
private static final String[] FILE_FLAG = {"--filename", "-f"};
|
||||||
|
|
||||||
private OutputStream out = null;
|
private OutputStream out = null;
|
||||||
private Map<Integer, List<MessageListener>> incomingMessageListeners = new HashMap<>();
|
private final Map<Integer, List<MessageListener>> incomingMessageListeners = new HashMap<>();
|
||||||
private Map<Integer, List<MessageListener>> outgoingMessageListeners = new HashMap<>();
|
private final Map<Integer, List<MessageListener>> outgoingMessageListeners = new HashMap<>();
|
||||||
private FlagsCheckListener flagRequestCallback = null;
|
private FlagsCheckListener flagRequestCallback = null;
|
||||||
|
|
||||||
|
private String getArgument(String[] args, String... arg) {
|
||||||
|
for (int i = 0; i < args.length - 1; i++) {
|
||||||
|
for (String str : arg) {
|
||||||
|
if (args[i].toLowerCase().equals(str.toLowerCase())) {
|
||||||
|
return args[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the connection with G-Earth, pass the arguments given in the Main method "super(args)"
|
* Makes the connection with G-Earth, pass the arguments given in the Main method "super(args)"
|
||||||
@ -41,29 +53,53 @@ public abstract class Extension {
|
|||||||
*/
|
*/
|
||||||
public Extension(String[] args) {
|
public Extension(String[] args) {
|
||||||
//obtain port
|
//obtain port
|
||||||
int port = 0;
|
this.args = args;
|
||||||
|
|
||||||
outerloop:
|
|
||||||
for (int i = 0; i < args.length - 1; i++) {
|
if (getInfoAnnotations() == null) {
|
||||||
for (String str : PORT_FLAG) {
|
System.err.println("Extension info not found\n\n" +
|
||||||
if (args[i].equals(str)) {
|
"Usage:\n" +
|
||||||
port = Integer.parseInt(args[i+1]);
|
"@ExtensionInfo ( \n" +
|
||||||
break outerloop;
|
" Title = \"...\",\n" +
|
||||||
}
|
" Description = \"...\",\n" +
|
||||||
}
|
" Version = \"...\",\n" +
|
||||||
|
" Author = \"...\"" +
|
||||||
|
"\n)");
|
||||||
|
isCorrupted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getArgument(args, PORT_FLAG) == null) {
|
||||||
|
System.err.println("Don't forget to include G-Earth's port in your program parameters (-p {port})");
|
||||||
|
isCorrupted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
if (isCorrupted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = Integer.parseInt(getArgument(args, PORT_FLAG));
|
||||||
|
String file = getArgument(args, FILE_FLAG);
|
||||||
|
|
||||||
Socket gEarthExtensionServer = null;
|
Socket gEarthExtensionServer = null;
|
||||||
try {
|
try {
|
||||||
gEarthExtensionServer = new Socket("localhost", port);
|
gEarthExtensionServer = new Socket("127.0.0.1", port);
|
||||||
|
|
||||||
InputStream in = gEarthExtensionServer.getInputStream();
|
InputStream in = gEarthExtensionServer.getInputStream();
|
||||||
DataInputStream dIn = new DataInputStream(in);
|
DataInputStream dIn = new DataInputStream(in);
|
||||||
out = gEarthExtensionServer.getOutputStream();
|
out = gEarthExtensionServer.getOutputStream();
|
||||||
|
|
||||||
while (!gEarthExtensionServer.isClosed()) {
|
while (!gEarthExtensionServer.isClosed()) {
|
||||||
|
|
||||||
int length = dIn.readInt();
|
int length;
|
||||||
|
try {
|
||||||
|
length = dIn.readInt();
|
||||||
|
}
|
||||||
|
catch(EOFException exception) {
|
||||||
|
//g-earth closed the extension
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] headerandbody = new byte[length + 4];
|
byte[] headerandbody = new byte[length + 4];
|
||||||
|
|
||||||
int amountRead = 0;
|
int amountRead = 0;
|
||||||
@ -77,11 +113,18 @@ public abstract class Extension {
|
|||||||
|
|
||||||
|
|
||||||
if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.INFOREQUEST) {
|
if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.INFOREQUEST) {
|
||||||
|
ExtensionInfo info = getInfoAnnotations();
|
||||||
|
|
||||||
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.EXTENSIONINFO);
|
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.EXTENSIONINFO);
|
||||||
response.appendString(getTitle())
|
response.appendString(info.Title())
|
||||||
.appendString(getAuthor())
|
.appendString(info.Author())
|
||||||
.appendString(getVersion())
|
.appendString(info.Version())
|
||||||
.appendString(getDescription());
|
.appendString(info.Description())
|
||||||
|
.appendBoolean(isOnClickMethodUsed())
|
||||||
|
.appendBoolean(file != null)
|
||||||
|
.appendString(file == null ? "": file)
|
||||||
|
.appendBoolean(CANLEAVE)
|
||||||
|
.appendBoolean(CANDELETE);
|
||||||
writeToStream(response.toBytes());
|
writeToStream(response.toBytes());
|
||||||
}
|
}
|
||||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.CONNECTIONSTART) {
|
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.CONNECTIONSTART) {
|
||||||
@ -121,19 +164,29 @@ public abstract class Extension {
|
|||||||
incomingMessageListeners :
|
incomingMessageListeners :
|
||||||
outgoingMessageListeners;
|
outgoingMessageListeners;
|
||||||
|
|
||||||
if (listeners.containsKey(-1)) { // registered on all packets
|
List<MessageListener> correctListeners = new ArrayList<>();
|
||||||
for (int i = listeners.get(-1).size() - 1; i >= 0; i--) {
|
|
||||||
listeners.get(-1).get(i).act(habboMessage);
|
synchronized (incomingMessageListeners) {
|
||||||
habboMessage.getPacket().setReadIndex(6);
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listeners.containsKey(habboPacket.headerId())) {
|
for(MessageListener listener : correctListeners) {
|
||||||
for (int i = listeners.get(habboPacket.headerId()).size() - 1; i >= 0; i--) {
|
habboMessage.getPacket().setReadIndex(6);
|
||||||
listeners.get(habboPacket.headerId()).get(i).act(habboMessage);
|
listener.act(habboMessage);
|
||||||
habboMessage.getPacket().setReadIndex(6);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
habboMessage.getPacket().setReadIndex(6);
|
||||||
|
|
||||||
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.MANIPULATEDPACKET);
|
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.MANIPULATEDPACKET);
|
||||||
response.appendLongString(habboMessage.stringify());
|
response.appendLongString(habboMessage.stringify());
|
||||||
@ -143,9 +196,9 @@ public abstract class Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException | ArrayIndexOutOfBoundsException e) {
|
} catch (IOException | ArrayIndexOutOfBoundsException e) {
|
||||||
e.printStackTrace();
|
System.err.println("Connection failed; is G-Earth active?");
|
||||||
|
// e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (gEarthExtensionServer != null && !gEarthExtensionServer.isClosed()) {
|
if (gEarthExtensionServer != null && !gEarthExtensionServer.isClosed()) {
|
||||||
@ -206,10 +259,13 @@ public abstract class Extension {
|
|||||||
incomingMessageListeners :
|
incomingMessageListeners :
|
||||||
outgoingMessageListeners;
|
outgoingMessageListeners;
|
||||||
|
|
||||||
if (!listeners.containsKey(headerId)) {
|
synchronized (listeners) {
|
||||||
listeners.put(headerId, new ArrayList<>());
|
if (!listeners.containsKey(headerId)) {
|
||||||
|
listeners.put(headerId, new ArrayList<>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
listeners.get(headerId).add(messageListener);
|
listeners.get(headerId).add(messageListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +305,25 @@ public abstract class Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
* Gets called when a connection has been established with G-Earth.
|
||||||
* This does not imply a connection with Habbo is setup.
|
* This does not imply a connection with Habbo is setup.
|
||||||
@ -270,8 +345,8 @@ public abstract class Extension {
|
|||||||
*/
|
*/
|
||||||
protected void onEndConnection(){}
|
protected void onEndConnection(){}
|
||||||
|
|
||||||
protected abstract String getTitle();
|
|
||||||
protected abstract String getDescription();
|
ExtensionInfo getInfoAnnotations() {
|
||||||
protected abstract String getVersion();
|
return getClass().getAnnotation(ExtensionInfo.class);
|
||||||
protected abstract String getAuthor();
|
}
|
||||||
}
|
}
|
||||||
|
114
src/main/extensions/ExtensionForm.java
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package main.extensions;
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import main.protocol.HMessage;
|
||||||
|
import main.protocol.HPacket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 22/09/18.
|
||||||
|
*/
|
||||||
|
public abstract class ExtensionForm extends Application {
|
||||||
|
|
||||||
|
private Extension extension = null;
|
||||||
|
protected static String[] args;
|
||||||
|
private volatile Stage primaryStage = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws Exception {
|
||||||
|
Platform.setImplicitExit(false);
|
||||||
|
setStageData(primaryStage);
|
||||||
|
this.primaryStage = primaryStage;
|
||||||
|
primaryStage.setOnCloseRequest(event -> {
|
||||||
|
event.consume();
|
||||||
|
Platform.runLater(primaryStage::hide);
|
||||||
|
});
|
||||||
|
ExtensionForm thiss = this;
|
||||||
|
|
||||||
|
ExtensionInfo extInfo = getClass().getAnnotation(ExtensionInfo.class);
|
||||||
|
|
||||||
|
Thread t = new Thread(() -> {
|
||||||
|
extension = new Extension(args) {
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
thiss.initExtension();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
thiss.onClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStartConnection() {
|
||||||
|
thiss.onStartConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEndConnection() {
|
||||||
|
thiss.onEndConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ExtensionInfo getInfoAnnotations() {
|
||||||
|
return extInfo;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
extension.run();
|
||||||
|
// Platform.runLater(primaryStage::close);
|
||||||
|
//when the extension has ended, close this process
|
||||||
|
Platform.exit();
|
||||||
|
});
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void setStageData(Stage primaryStage) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
|
//wrap extension methods
|
||||||
|
protected boolean requestFlags(Extension.FlagsCheckListener flagRequestCallback){
|
||||||
|
return extension.requestFlags(flagRequestCallback);
|
||||||
|
}
|
||||||
|
protected void writeToConsole(String s) {
|
||||||
|
extension.writeToConsole(s);
|
||||||
|
}
|
||||||
|
protected void intercept(HMessage.Side side, Extension.MessageListener messageListener) {
|
||||||
|
extension.intercept(side, messageListener);
|
||||||
|
}
|
||||||
|
protected void intercept(HMessage.Side side, int headerId, Extension.MessageListener messageListener){
|
||||||
|
extension.intercept(side, headerId, messageListener);
|
||||||
|
}
|
||||||
|
protected boolean sendToServer(HPacket packet){
|
||||||
|
return extension.sendToServer(packet);
|
||||||
|
}
|
||||||
|
protected boolean sendToClient(HPacket packet){
|
||||||
|
return extension.sendToClient(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets called when a connection has been established with G-Earth.
|
||||||
|
* This does not imply a connection with Habbo is setup.
|
||||||
|
*/
|
||||||
|
protected void initExtension(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application got doubleclicked from the G-Earth interface. Doing something here is optional
|
||||||
|
*/
|
||||||
|
private void onClick(){
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
primaryStage.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A connection with Habbo has been started
|
||||||
|
*/
|
||||||
|
protected void onStartConnection(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A connection with Habbo has ended
|
||||||
|
*/
|
||||||
|
protected void onEndConnection(){}
|
||||||
|
}
|
15
src/main/extensions/ExtensionInfo.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package main.extensions;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 25/09/18.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ExtensionInfo {
|
||||||
|
String Title();
|
||||||
|
String Description();
|
||||||
|
String Version();
|
||||||
|
String Author();
|
||||||
|
}
|
@ -1,17 +1,26 @@
|
|||||||
package main.extensions.examples;
|
package main.extensions.examples.adminonconnect;
|
||||||
|
|
||||||
import main.extensions.Extension;
|
import main.extensions.Extension;
|
||||||
|
import main.extensions.ExtensionInfo;
|
||||||
import main.protocol.HMessage;
|
import main.protocol.HMessage;
|
||||||
import main.protocol.HPacket;
|
import main.protocol.HPacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 26/06/18.
|
* Created by Jonas on 26/06/18.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ExtensionInfo(
|
||||||
|
Title = "Always admin!",
|
||||||
|
Description = "Gives you admin permission on connect",
|
||||||
|
Version = "1.0",
|
||||||
|
Author = "sirjonasxx"
|
||||||
|
)
|
||||||
public class AdminOnConnect extends Extension {
|
public class AdminOnConnect extends Extension {
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new AdminOnConnect(args);
|
new AdminOnConnect(args).run();
|
||||||
}
|
}
|
||||||
public AdminOnConnect(String[] args) {
|
public AdminOnConnect(String[] args) {
|
||||||
super(args);
|
super(args);
|
||||||
@ -39,22 +48,4 @@ public class AdminOnConnect extends Extension {
|
|||||||
protected void onStartConnection() {
|
protected void onStartConnection() {
|
||||||
done = false;
|
done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onClick() {
|
|
||||||
System.out.println("clicked");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getTitle() {
|
|
||||||
return "Always admin!";
|
|
||||||
}
|
|
||||||
protected String getDescription() {
|
|
||||||
return "Gives you admin permission on connect";
|
|
||||||
}
|
|
||||||
protected String getVersion() {
|
|
||||||
return "1.0";
|
|
||||||
}
|
|
||||||
protected String getAuthor() {
|
|
||||||
return "sirjonasxx";
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package main.extensions.examples.blockreplacepackets;
|
||||||
|
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import main.extensions.ExtensionForm;
|
||||||
|
import main.extensions.ExtensionInfo;
|
||||||
|
import main.ui.GEarthController;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 22/09/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ExtensionInfo(
|
||||||
|
Title = "iManipulate",
|
||||||
|
Description = "Block &/ replace packets",
|
||||||
|
Version = "0.1",
|
||||||
|
Author = "sirjonasxx"
|
||||||
|
)
|
||||||
|
public class BlockAndReplacePackets extends ExtensionForm {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ExtensionForm.args = args;
|
||||||
|
launch(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initExtension() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStageData(Stage primaryStage) throws Exception {
|
||||||
|
FXMLLoader loader = new FXMLLoader(BlockAndReplacePackets.class.getResource("blockreplace.fxml"));
|
||||||
|
Parent root = loader.load();
|
||||||
|
|
||||||
|
primaryStage.setTitle("Packet blocker and replacer");
|
||||||
|
primaryStage.setScene(new Scene(root, 565, 262));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.TextArea?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
|
||||||
|
<GridPane prefHeight="260.0" prefWidth="179.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.extensions.examples.blockreplacepackets.BlockAndReplacePackets">
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="367.0" minWidth="10.0" prefWidth="163.0" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
|
</rowConstraints>
|
||||||
|
<children>
|
||||||
|
<GridPane>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints maxHeight="121.0" minHeight="10.0" prefHeight="28.0" vgrow="SOMETIMES" />
|
||||||
|
<RowConstraints maxHeight="234.0" minHeight="10.0" prefHeight="234.0" vgrow="SOMETIMES" />
|
||||||
|
</rowConstraints>
|
||||||
|
<children>
|
||||||
|
<TextArea fx:id="text" editable="false" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||||
|
</GridPane.margin>
|
||||||
|
</TextArea>
|
||||||
|
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" text="Blocks packets:" textAlignment="CENTER" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
@ -1,6 +1,7 @@
|
|||||||
package main.extensions.examples;
|
package main.extensions.examples.speechcolorizer;
|
||||||
|
|
||||||
import main.extensions.Extension;
|
import main.extensions.Extension;
|
||||||
|
import main.extensions.ExtensionInfo;
|
||||||
import main.protocol.HMessage;
|
import main.protocol.HMessage;
|
||||||
import main.protocol.HPacket;
|
import main.protocol.HPacket;
|
||||||
|
|
||||||
@ -15,11 +16,16 @@ import java.util.Random;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ExtensionInfo(
|
||||||
|
Title = "Colorize me!",
|
||||||
|
Description = "Because we like to be weird",
|
||||||
|
Version = "1.0",
|
||||||
|
Author = "sirjonasxx"
|
||||||
|
)
|
||||||
public class SpeechColorizer extends Extension {
|
public class SpeechColorizer extends Extension {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new SpeechColorizer(args);
|
new SpeechColorizer(args).run();
|
||||||
}
|
}
|
||||||
private SpeechColorizer(String[] args) {
|
private SpeechColorizer(String[] args) {
|
||||||
super(args);
|
super(args);
|
7
src/main/extensions/extra/Inspector.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package main.extensions.extra;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 22/09/18.
|
||||||
|
*/
|
||||||
|
public class Inspector {
|
||||||
|
}
|
@ -1,183 +1,71 @@
|
|||||||
package main.misc;
|
package main.misc;
|
||||||
|
|
||||||
import java.io.*;
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 05/04/18.
|
* Created by Jonas on 28/09/18.
|
||||||
*/
|
*/
|
||||||
public class Cacher {
|
public class Cacher {
|
||||||
|
|
||||||
|
private static final String CACHEFILENAME = "jsoncache.json";
|
||||||
|
|
||||||
private static String getCacheDir() {
|
private static String getCacheDir() {
|
||||||
return System.getProperty("user.home") + File.separator + ".G-Earth" + File.separator;
|
return System.getProperty("user.home") + File.separator + ".G-Earth" + File.separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean exists(String key) {
|
private static boolean cacheFileExists() {
|
||||||
File f = new File(getCacheDir(), "cache.txt");
|
File f = new File(getCacheDir(), CACHEFILENAME);
|
||||||
if (f.exists()) {
|
return (f.exists() && !f.isDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JSONObject getCacheContents() {
|
||||||
|
if (cacheFileExists()) {
|
||||||
try {
|
try {
|
||||||
List<String> lines = Files.readAllLines(f.toPath());
|
File f = new File(getCacheDir(), CACHEFILENAME);
|
||||||
|
String contents = String.join("\n", Files.readAllLines(f.toPath()));
|
||||||
|
|
||||||
for (String line : lines) {
|
JSONParser parser = new JSONParser();
|
||||||
if (line.startsWith(key+":")) {
|
return (JSONObject) parser.parse(contents);
|
||||||
return true;
|
} catch (IOException | ParseException e) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return new JSONObject();
|
||||||
}
|
}
|
||||||
|
private static void updateCache(JSONObject contents) {
|
||||||
|
try (FileWriter file = new FileWriter(new File(getCacheDir(), CACHEFILENAME))) {
|
||||||
|
|
||||||
public static String get(String key) {
|
file.write(contents.toJSONString());
|
||||||
File f = new File(getCacheDir(), "cache.txt");
|
file.flush();
|
||||||
if (f.exists()) {
|
|
||||||
try {
|
|
||||||
List<String> lines = Files.readAllLines(f.toPath());
|
|
||||||
|
|
||||||
for (String line : lines) {
|
} catch (IOException e) {
|
||||||
if (line.startsWith(key+":")) {
|
e.printStackTrace();
|
||||||
return line.split(":")[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void remove(String key) {
|
|
||||||
File targetFile = new File(getCacheDir() + File.separator + "cache.txt");
|
|
||||||
File parent = targetFile.getParentFile();
|
|
||||||
if (!parent.exists() && !parent.mkdirs()) {
|
|
||||||
throw new IllegalStateException("Couldn't create dir: " + parent);
|
|
||||||
}
|
|
||||||
if (!targetFile.exists()) {
|
|
||||||
try {
|
|
||||||
targetFile.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ArrayList<String> lines = new ArrayList<String>();
|
|
||||||
File f1 = new File(getCacheDir() + File.separator + "cache.txt");
|
|
||||||
FileReader fr = new FileReader(f1);
|
|
||||||
BufferedReader br = new BufferedReader(fr);
|
|
||||||
String line = null;
|
|
||||||
while ((line = br.readLine()) != null)
|
|
||||||
{
|
|
||||||
if (!line.startsWith(key + ":"))
|
|
||||||
lines.add(line);
|
|
||||||
|
|
||||||
}
|
|
||||||
fr.close();
|
|
||||||
br.close();
|
|
||||||
|
|
||||||
FileWriter fw = new FileWriter(f1);
|
|
||||||
BufferedWriter out = new BufferedWriter(fw);
|
|
||||||
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
|
||||||
out.write(lines.get(i));
|
|
||||||
if (i != lines.size() - 1) out.write("\n");
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void add(String key, String value) {
|
public static void put(String key, Object val) {
|
||||||
File targetFile = new File(getCacheDir() + File.separator + "cache.txt");
|
JSONObject object = getCacheContents();
|
||||||
File parent = targetFile.getParentFile();
|
if (object.containsKey(key)) object.remove(key);
|
||||||
if (!parent.exists() && !parent.mkdirs()) {
|
|
||||||
throw new IllegalStateException("Couldn't create dir: " + parent);
|
|
||||||
}
|
|
||||||
if (!targetFile.exists()) {
|
|
||||||
try {
|
|
||||||
targetFile.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// File f = new File(getCacheDir(), "cache.txt");
|
object.put(key, val);
|
||||||
// if (!f.exists()) {
|
updateCache(object);
|
||||||
// try {
|
|
||||||
// PrintWriter writer = new PrintWriter(f.getPath(), "UTF-8");
|
|
||||||
// writer.write("");
|
|
||||||
// writer.close();
|
|
||||||
// } catch (FileNotFoundException | UnsupportedEncodingException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ArrayList<String> lines = new ArrayList<String>();
|
|
||||||
File f1 = new File(getCacheDir() + File.separator + "cache.txt");
|
|
||||||
FileReader fr = new FileReader(f1);
|
|
||||||
BufferedReader br = new BufferedReader(fr);
|
|
||||||
String line = null;
|
|
||||||
boolean containmmm = false;
|
|
||||||
while ((line = br.readLine()) != null)
|
|
||||||
{
|
|
||||||
if (line.startsWith(key+":"))
|
|
||||||
containmmm = true;
|
|
||||||
lines.add(line);
|
|
||||||
|
|
||||||
}
|
|
||||||
fr.close();
|
|
||||||
br.close();
|
|
||||||
|
|
||||||
FileWriter fw = new FileWriter(f1);
|
|
||||||
BufferedWriter out = new BufferedWriter(fw);
|
|
||||||
|
|
||||||
if (!containmmm) {
|
|
||||||
out.write(key+":"+value);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
|
||||||
out.write("\n"+ lines.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
public static Object get(String key) {
|
||||||
|
JSONObject object = getCacheContents();
|
||||||
|
|
||||||
public static void update(String key, String value) {
|
return object.get(key);
|
||||||
remove(key);
|
|
||||||
add(key, value);
|
|
||||||
}
|
}
|
||||||
|
public static void clear() {
|
||||||
|
updateCache(new JSONObject());
|
||||||
public static void main(String[] args) {
|
|
||||||
// System.out.println(exists("hallo"));
|
|
||||||
// System.out.println(get("hallo"));
|
|
||||||
//
|
|
||||||
// add("hallo","doei");
|
|
||||||
//
|
|
||||||
// System.out.println(exists("hallo"));
|
|
||||||
// System.out.println(get("hallo"));
|
|
||||||
//
|
|
||||||
// remove("hallo");
|
|
||||||
// System.out.println(get("hallo"));
|
|
||||||
System.out.println(get("PRODUCTION-201804032203-770536283-pingHeader"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
src/main/misc/ConfirmationDialog.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package main.misc;
|
||||||
|
|
||||||
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.CheckBox;
|
||||||
|
import javafx.scene.control.DialogPane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 27/09/18.
|
||||||
|
*/
|
||||||
|
public class ConfirmationDialog {
|
||||||
|
|
||||||
|
public static boolean showDialog = true;
|
||||||
|
|
||||||
|
public static Alert createAlertWithOptOut(Alert.AlertType type, String title, String headerText,
|
||||||
|
String message, String optOutMessage, /*Callback<Boolean, Void> optOutAction,*/
|
||||||
|
ButtonType... buttonTypes) {
|
||||||
|
Alert alert = new Alert(type);
|
||||||
|
// Need to force the alert to layout in order to grab the graphic,
|
||||||
|
// as we are replacing the dialog pane with a custom pane
|
||||||
|
alert.getDialogPane().applyCss();
|
||||||
|
Node graphic = alert.getDialogPane().getGraphic();
|
||||||
|
// Create a new dialog pane that has a checkbox instead of the hide/show details button
|
||||||
|
// Use the supplied callback for the action of the checkbox
|
||||||
|
alert.setDialogPane(new DialogPane() {
|
||||||
|
@Override
|
||||||
|
protected Node createDetailsButton() {
|
||||||
|
CheckBox optOut = new CheckBox();
|
||||||
|
optOut.setText(optOutMessage);
|
||||||
|
optOut.setOnAction(event -> showDialog = !optOut.isSelected());
|
||||||
|
return optOut;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alert.getDialogPane().getButtonTypes().addAll(buttonTypes);
|
||||||
|
alert.getDialogPane().setContentText(message);
|
||||||
|
// Fool the dialog into thinking there is some expandable content
|
||||||
|
// a Group won't take up any space if it has no children
|
||||||
|
alert.getDialogPane().setExpandableContent(new Group());
|
||||||
|
alert.getDialogPane().setExpanded(true);
|
||||||
|
// Reset the dialog graphic using the default style
|
||||||
|
alert.getDialogPane().setGraphic(graphic);
|
||||||
|
alert.setTitle(title);
|
||||||
|
alert.setHeaderText(headerText);
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package main.protocol;
|
package main.protocol;
|
||||||
|
|
||||||
|
import main.misc.Cacher;
|
||||||
import main.protocol.hostreplacer.HostReplacer;
|
import main.protocol.hostreplacer.HostReplacer;
|
||||||
import main.protocol.hostreplacer.HostReplacerFactory;
|
import main.protocol.hostreplacer.HostReplacerFactory;
|
||||||
import main.protocol.memory.Rc4Obtainer;
|
import main.protocol.memory.Rc4Obtainer;
|
||||||
@ -16,6 +17,7 @@ import java.util.*;
|
|||||||
|
|
||||||
public class HConnection {
|
public class HConnection {
|
||||||
|
|
||||||
|
public static final String HOTELS_CACHE_KEY = "hotelsConnectionInfo";
|
||||||
|
|
||||||
private final Queue<HPacket> sendToClientAsyncQueue = new LinkedList<>();
|
private final Queue<HPacket> sendToClientAsyncQueue = new LinkedList<>();
|
||||||
private final Queue<HPacket> sendToServerAsyncQueue = new LinkedList<>();
|
private final Queue<HPacket> sendToServerAsyncQueue = new LinkedList<>();
|
||||||
@ -63,16 +65,27 @@ public class HConnection {
|
|||||||
CONNECTED // CONNECTED
|
CONNECTED // CONNECTED
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> autoDetectHosts;
|
public static List<String> autoDetectHosts;
|
||||||
static {
|
static {
|
||||||
autoDetectHosts = new ArrayList<>();
|
autoDetectHosts = new ArrayList<>();
|
||||||
autoDetectHosts.add("game-us.habbo.com:38101");
|
|
||||||
autoDetectHosts.add("game-nl.habbo.com:30000");
|
|
||||||
autoDetectHosts.add("game-br.habbo.com:30000");
|
autoDetectHosts.add("game-br.habbo.com:30000");
|
||||||
|
autoDetectHosts.add("game-de.habbo.com:30000");
|
||||||
autoDetectHosts.add("game-es.habbo.com:30000");
|
autoDetectHosts.add("game-es.habbo.com:30000");
|
||||||
|
autoDetectHosts.add("game-fi.habbo.com:30000");
|
||||||
autoDetectHosts.add("game-fr.habbo.com:30000");
|
autoDetectHosts.add("game-fr.habbo.com:30000");
|
||||||
|
autoDetectHosts.add("game-it.habbo.com:30000");
|
||||||
autoDetectHosts.add("game-nl.habbo.com:30000");
|
autoDetectHosts.add("game-nl.habbo.com:30000");
|
||||||
autoDetectHosts.add("game-tr.habbo.com:30000");
|
autoDetectHosts.add("game-tr.habbo.com:30000");
|
||||||
|
autoDetectHosts.add("game-us.habbo.com:38101");
|
||||||
|
|
||||||
|
List<String> additionalCachedHotels = (List<String>) Cacher.get(HOTELS_CACHE_KEY);
|
||||||
|
if (additionalCachedHotels != null) {
|
||||||
|
for (String additionalHotel : additionalCachedHotels) {
|
||||||
|
if (!autoDetectHosts.contains(additionalHotel)) {
|
||||||
|
autoDetectHosts.add(additionalHotel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -110,6 +123,16 @@ public class HConnection {
|
|||||||
|
|
||||||
// manual method
|
// manual method
|
||||||
public void prepare(String domain, int port) {
|
public void prepare(String domain, int port) {
|
||||||
|
List<String> additionalCachedHotels = (List<String>) Cacher.get(HOTELS_CACHE_KEY);
|
||||||
|
if (additionalCachedHotels == null) {
|
||||||
|
additionalCachedHotels = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (!additionalCachedHotels.contains(domain +":"+port)) {
|
||||||
|
additionalCachedHotels.add(domain+":"+port);
|
||||||
|
Cacher.put(HOTELS_CACHE_KEY, additionalCachedHotels);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<String> potentialHost = new ArrayList<>();
|
List<String> potentialHost = new ArrayList<>();
|
||||||
potentialHost.add(domain+":"+port);
|
potentialHost.add(domain+":"+port);
|
||||||
prepare(potentialHost);
|
prepare(potentialHost);
|
||||||
@ -134,17 +157,29 @@ public class HConnection {
|
|||||||
removeFromHosts();
|
removeFromHosts();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
for (String host : allPotentialHosts) {
|
|
||||||
InetAddress address = InetAddress.getByName(host.split(":")[0]);
|
|
||||||
actual_domain.add(address.getHostAddress());
|
|
||||||
}
|
|
||||||
setState(State.PREPARED);
|
|
||||||
|
|
||||||
} catch (UnknownHostException e) {
|
List<String> willremove = new ArrayList<>();
|
||||||
e.printStackTrace();
|
for (String host : allPotentialHosts) {
|
||||||
setState(State.NOT_CONNECTED);
|
InetAddress address = null;
|
||||||
|
try {
|
||||||
|
address = InetAddress.getByName(host.split(":")[0]);
|
||||||
|
actual_domain.add(address.getHostAddress());
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
actual_domain.add(null);
|
||||||
|
willremove.add(host);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> additionalCachedHotels = (List<String>) Cacher.get(HOTELS_CACHE_KEY);
|
||||||
|
if (additionalCachedHotels != null) {
|
||||||
|
for (String host: willremove) {
|
||||||
|
additionalCachedHotels.remove(host);
|
||||||
|
}
|
||||||
|
Cacher.put(HOTELS_CACHE_KEY, additionalCachedHotels);
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(State.PREPARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() throws IOException {
|
public void start() throws IOException {
|
||||||
@ -157,6 +192,8 @@ public class HConnection {
|
|||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < actual_domain.size(); i++) {
|
for (int i = 0; i < actual_domain.size(); i++) {
|
||||||
|
if (actual_domain.get(i) == null) continue;
|
||||||
|
|
||||||
ServerSocket proxy = new ServerSocket(port.get(i), 10, InetAddress.getByName("127.0.0." + (i+1)));
|
ServerSocket proxy = new ServerSocket(port.get(i), 10, InetAddress.getByName("127.0.0." + (i+1)));
|
||||||
this.proxy.add(proxy);
|
this.proxy.add(proxy);
|
||||||
String dom = actual_domain.get(i);
|
String dom = actual_domain.get(i);
|
||||||
@ -186,7 +223,7 @@ public class HConnection {
|
|||||||
|
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
//e1.printStackTrace();
|
// e1.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -359,17 +396,31 @@ public class HConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addToHosts() {
|
private void addToHosts() {
|
||||||
String[] lines = new String[input_domain.size()];
|
List<String> linesTemp = new ArrayList<>();
|
||||||
for (int i = 0; i < input_domain.size(); i++) {
|
for (int i = 0; i < input_domain.size(); i++) {
|
||||||
lines[i] = ("127.0.0." + (i+1)) + " " + input_domain.get(i);
|
if (actual_domain.get(i) != null) {
|
||||||
|
linesTemp.add(("127.0.0." + (i+1)) + " " + input_domain.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] lines = new String[linesTemp.size()];
|
||||||
|
for (int i = 0; i < linesTemp.size(); i++) {
|
||||||
|
lines[i] = linesTemp.get(i);
|
||||||
}
|
}
|
||||||
hostsReplacer.addRedirect(lines);
|
hostsReplacer.addRedirect(lines);
|
||||||
hostRedirected = true;
|
hostRedirected = true;
|
||||||
}
|
}
|
||||||
private void removeFromHosts(){
|
private void removeFromHosts(){
|
||||||
String[] lines = new String[input_domain.size()];
|
List<String> linesTemp = new ArrayList<>();
|
||||||
for (int i = 0; i < input_domain.size(); i++) {
|
for (int i = 0; i < input_domain.size(); i++) {
|
||||||
lines[i] = ("127.0.0." + (i+1)) + " " + input_domain.get(i);
|
if (actual_domain.get(i) != null) {
|
||||||
|
linesTemp.add(("127.0.0." + (i+1)) + " " + input_domain.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] lines = new String[linesTemp.size()];
|
||||||
|
for (int i = 0; i < linesTemp.size(); i++) {
|
||||||
|
lines[i] = linesTemp.get(i);
|
||||||
}
|
}
|
||||||
hostsReplacer.removeRedirect(lines);
|
hostsReplacer.removeRedirect(lines);
|
||||||
hostRedirected = false;
|
hostRedirected = false;
|
||||||
|
@ -72,6 +72,7 @@ public class Rc4Obtainer {
|
|||||||
|
|
||||||
if (payloadBuffer.peak().length == 0) {
|
if (payloadBuffer.peak().length == 0) {
|
||||||
outgoingHandler.setRc4(rc4Tryout);
|
outgoingHandler.setRc4(rc4Tryout);
|
||||||
|
incomingHandler.setRc4(rc4Tryout);
|
||||||
break outerloop;
|
break outerloop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package main.protocol.packethandler;
|
|||||||
|
|
||||||
import main.protocol.HMessage;
|
import main.protocol.HMessage;
|
||||||
import main.protocol.TrafficListener;
|
import main.protocol.TrafficListener;
|
||||||
|
import main.protocol.crypto.RC4;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -10,6 +11,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public abstract class Handler {
|
public abstract class Handler {
|
||||||
|
|
||||||
|
protected static final boolean DEBUG = false;
|
||||||
|
|
||||||
volatile PayloadBuffer payloadBuffer = new PayloadBuffer();
|
volatile PayloadBuffer payloadBuffer = new PayloadBuffer();
|
||||||
volatile OutputStream out;
|
volatile OutputStream out;
|
||||||
volatile Object[] listeners = null; //get notified on packet send
|
volatile Object[] listeners = null; //get notified on packet send
|
||||||
@ -17,6 +20,9 @@ public abstract class Handler {
|
|||||||
volatile boolean isDataStream = false;
|
volatile boolean isDataStream = false;
|
||||||
volatile int currentIndex = 0;
|
volatile int currentIndex = 0;
|
||||||
|
|
||||||
|
protected RC4 clientcipher = null;
|
||||||
|
protected RC4 servercipher = null;
|
||||||
|
|
||||||
|
|
||||||
public Handler(OutputStream outputStream, Object[] listeners) {
|
public Handler(OutputStream outputStream, Object[] listeners) {
|
||||||
this.listeners = listeners;
|
this.listeners = listeners;
|
||||||
@ -28,18 +34,11 @@ public abstract class Handler {
|
|||||||
isDataStream = true;
|
isDataStream = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void act(byte[] buffer) throws IOException {
|
public abstract void act(byte[] buffer) throws IOException;
|
||||||
if (isDataStream) {
|
|
||||||
payloadBuffer.push(buffer);
|
|
||||||
notifyBufferListeners(buffer.length);
|
|
||||||
|
|
||||||
if (!isTempBlocked) {
|
public void setRc4(RC4 rc4) {
|
||||||
flush();
|
this.clientcipher = rc4.deepCopy();
|
||||||
}
|
this.servercipher = rc4.deepCopy();
|
||||||
}
|
|
||||||
else {
|
|
||||||
out.write(buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void block() {
|
public void block() {
|
||||||
@ -73,7 +72,7 @@ public abstract class Handler {
|
|||||||
|
|
||||||
public abstract void flush() throws IOException;
|
public abstract void flush() throws IOException;
|
||||||
|
|
||||||
|
protected abstract void printForDebugging(byte[] bytes);
|
||||||
|
|
||||||
private List<BufferListener> bufferListeners = new ArrayList<>();
|
private List<BufferListener> bufferListeners = new ArrayList<>();
|
||||||
public void addBufferListener(BufferListener listener) {
|
public void addBufferListener(BufferListener listener) {
|
||||||
|
@ -13,13 +13,48 @@ public class IncomingHandler extends Handler {
|
|||||||
super(outputStream, listeners);
|
super(outputStream, listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
private Boolean isEncryptedStream = null;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void act(byte[] buffer) throws IOException {
|
||||||
|
if (isDataStream) {
|
||||||
|
if (DEBUG) {
|
||||||
|
printForDebugging(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isEncryptedStream == null || !isEncryptedStream) {
|
||||||
|
payloadBuffer.push(buffer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
payloadBuffer.push(servercipher.rc4(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
notifyBufferListeners(buffer.length);
|
||||||
|
|
||||||
|
if (!isTempBlocked) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.write(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendToStream(byte[] buffer) {
|
public void sendToStream(byte[] buffer) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
try {
|
try {
|
||||||
out.write(buffer);
|
out.write(
|
||||||
|
(isEncryptedStream == null || !isEncryptedStream)
|
||||||
|
? buffer
|
||||||
|
: clientcipher.rc4(buffer)
|
||||||
|
);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -33,14 +68,29 @@ public class IncomingHandler extends Handler {
|
|||||||
|
|
||||||
for (HPacket hpacket : hpackets){
|
for (HPacket hpacket : hpackets){
|
||||||
HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOCLIENT, currentIndex);
|
HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOCLIENT, currentIndex);
|
||||||
if (isDataStream) notifyListeners(hMessage);
|
if (isDataStream) {
|
||||||
|
notifyListeners(hMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if (!hMessage.isBlocked()) {
|
if (!hMessage.isBlocked()) {
|
||||||
out.write(hMessage.getPacket().toBytes());
|
out.write(
|
||||||
|
(isEncryptedStream == null || !isEncryptedStream)
|
||||||
|
? hMessage.getPacket().toBytes()
|
||||||
|
: clientcipher.rc4(hMessage.getPacket().toBytes())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDataStream && isEncryptedStream == null && hpacket.length() == 261) {
|
||||||
|
isEncryptedStream = hpacket.readBoolean(264);
|
||||||
}
|
}
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void printForDebugging(byte[] bytes) {
|
||||||
|
System.out.println("-- DEBUG INCOMING -- " + new HPacket(bytes).toString() + " -- DEBUG --");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,7 @@ public class OutgoingHandler extends Handler {
|
|||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
|
||||||
private final static int encryptOffset = 3; //all packets with index < 3 aren't encrypted
|
private final static int encryptOffset = 3; //all packets with index < 3 aren't encrypted
|
||||||
private RC4 clientcipher = null;
|
|
||||||
private RC4 servercipher = null;
|
|
||||||
private List<Byte> tempEncryptedBuffer = new ArrayList<>();
|
private List<Byte> tempEncryptedBuffer = new ArrayList<>();
|
||||||
|
|
||||||
public OutgoingHandler(OutputStream outputStream, Object[] listeners) {
|
public OutgoingHandler(OutputStream outputStream, Object[] listeners) {
|
||||||
@ -35,7 +32,6 @@ public class OutgoingHandler extends Handler {
|
|||||||
public void act(byte[] buffer) throws IOException {
|
public void act(byte[] buffer) throws IOException {
|
||||||
dataStreamCheck(buffer);
|
dataStreamCheck(buffer);
|
||||||
if (isDataStream) {
|
if (isDataStream) {
|
||||||
|
|
||||||
if (currentIndex < encryptOffset) {
|
if (currentIndex < encryptOffset) {
|
||||||
payloadBuffer.push(buffer);
|
payloadBuffer.push(buffer);
|
||||||
}
|
}
|
||||||
@ -45,7 +41,11 @@ public class OutgoingHandler extends Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
payloadBuffer.push(clientcipher.rc4(buffer));
|
byte[] tm = clientcipher.rc4(buffer);
|
||||||
|
if (DEBUG) {
|
||||||
|
printForDebugging(tm);
|
||||||
|
}
|
||||||
|
payloadBuffer.push(tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyBufferListeners(buffer.length);
|
notifyBufferListeners(buffer.length);
|
||||||
@ -60,20 +60,8 @@ public class OutgoingHandler extends Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendToStream(byte[] buffer) {
|
|
||||||
synchronized (lock) {
|
|
||||||
try {
|
|
||||||
out.write(servercipher.rc4(buffer));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRc4(RC4 rc4) {
|
public void setRc4(RC4 rc4) {
|
||||||
this.clientcipher = rc4;
|
super.setRc4(rc4);
|
||||||
this.servercipher = rc4.deepCopy();
|
|
||||||
|
|
||||||
byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
|
byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
|
||||||
for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
|
for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
|
||||||
@ -87,6 +75,19 @@ public class OutgoingHandler extends Handler {
|
|||||||
}
|
}
|
||||||
tempEncryptedBuffer = null;
|
tempEncryptedBuffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendToStream(byte[] buffer) {
|
||||||
|
synchronized (lock) {
|
||||||
|
try {
|
||||||
|
out.write(servercipher.rc4(buffer));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public List<Byte> getEncryptedBuffer() {
|
public List<Byte> getEncryptedBuffer() {
|
||||||
return tempEncryptedBuffer;
|
return tempEncryptedBuffer;
|
||||||
}
|
}
|
||||||
@ -109,4 +110,10 @@ public class OutgoingHandler extends Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void printForDebugging(byte[] bytes) {
|
||||||
|
System.out.println("-- DEBUG OUTGOING -- " + new HPacket(bytes).toString() + " -- DEBUG --");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class BoxButton extends StackPane {
|
public class BoxButton extends StackPane {
|
||||||
|
|
||||||
private ImageView imageView;
|
private ImageView imageView;
|
||||||
@ -15,9 +17,9 @@ public class BoxButton extends StackPane {
|
|||||||
private boolean isVisible;
|
private boolean isVisible;
|
||||||
|
|
||||||
//paths zijn relatief aan deze classpath
|
//paths zijn relatief aan deze classpath
|
||||||
public BoxButton(String imagePath, String imageOnHoverPath) {
|
public BoxButton(String imageName, String imageOnHoverName) {
|
||||||
this.image = new Image(getClass().getResourceAsStream(imagePath));
|
this.image = new Image(getClass().getResourceAsStream("files" + File.separator + imageName));
|
||||||
this.imageOnHover = new Image(getClass().getResourceAsStream(imageOnHoverPath));
|
this.imageOnHover = new Image(getClass().getResourceAsStream("files" + File.separator + imageOnHoverName));
|
||||||
this.imageView = new ImageView();
|
this.imageView = new ImageView();
|
||||||
|
|
||||||
setCursor(Cursor.DEFAULT);
|
setCursor(Cursor.DEFAULT);
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package main.ui.buttons;
|
package main.ui.buttons;
|
||||||
|
|
||||||
|
import org.omg.CORBA.Environment;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class DeleteButton extends BoxButton {
|
public class DeleteButton extends BoxButton {
|
||||||
|
|
||||||
public DeleteButton() {
|
public DeleteButton() {
|
||||||
|
10
src/main/ui/buttons/ExitButton.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package main.ui.buttons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 26/09/18.
|
||||||
|
*/
|
||||||
|
public class ExitButton extends BoxButton {
|
||||||
|
public ExitButton() {
|
||||||
|
super("ButtonExit.png", "ButtonExitHover.png");
|
||||||
|
}
|
||||||
|
}
|
10
src/main/ui/buttons/FireButton.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package main.ui.buttons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 26/09/18.
|
||||||
|
*/
|
||||||
|
public class FireButton extends BoxButton {
|
||||||
|
public FireButton() {
|
||||||
|
super("ButtonFire.png", "ButtonFireHover.png");
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import javafx.scene.image.ImageView;
|
|||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -31,10 +32,10 @@ public class PauseResumeButton extends StackPane{
|
|||||||
public PauseResumeButton(boolean isPaused) {
|
public PauseResumeButton(boolean isPaused) {
|
||||||
this.isPaused[0] = isPaused;
|
this.isPaused[0] = isPaused;
|
||||||
|
|
||||||
this.imagePause = new Image(getClass().getResourceAsStream("ButtonPause.png"));
|
this.imagePause = new Image(getClass().getResourceAsStream("files"+ File.separator+"ButtonPause.png"));
|
||||||
this.imagePauseOnHover = new Image(getClass().getResourceAsStream("ButtonPauseHover.png"));
|
this.imagePauseOnHover = new Image(getClass().getResourceAsStream("files"+ File.separator+"ButtonPauseHover.png"));
|
||||||
this.imageResume = new Image(getClass().getResourceAsStream("ButtonResume.png"));
|
this.imageResume = new Image(getClass().getResourceAsStream("files"+ File.separator+"ButtonResume.png"));
|
||||||
this.imageResumeOnHover = new Image(getClass().getResourceAsStream("ButtonResumeHover.png"));
|
this.imageResumeOnHover = new Image(getClass().getResourceAsStream("files"+ File.separator+"ButtonResumeHover.png"));
|
||||||
this.imageView = new ImageView();
|
this.imageView = new ImageView();
|
||||||
|
|
||||||
setCursor(Cursor.DEFAULT);
|
setCursor(Cursor.DEFAULT);
|
||||||
|
9
src/main/ui/buttons/ReloadButton.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package main.ui.buttons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 26/09/18.
|
||||||
|
*/
|
||||||
|
public class ReloadButton extends BoxButton {
|
||||||
|
public ReloadButton() {
|
||||||
|
super("ButtonReload.png", "ButtonReloadHover.png"); }
|
||||||
|
}
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 443 B |
Before Width: | Height: | Size: 460 B After Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 454 B |
BIN
src/main/ui/buttons/files/ButtonExit.png
Normal file
After Width: | Height: | Size: 644 B |
BIN
src/main/ui/buttons/files/ButtonExitHover.png
Normal file
After Width: | Height: | Size: 538 B |
BIN
src/main/ui/buttons/files/ButtonFire.png
Normal file
After Width: | Height: | Size: 677 B |
BIN
src/main/ui/buttons/files/ButtonFireHover.png
Normal file
After Width: | Height: | Size: 642 B |
Before Width: | Height: | Size: 725 B After Width: | Height: | Size: 725 B |
Before Width: | Height: | Size: 621 B After Width: | Height: | Size: 621 B |
BIN
src/main/ui/buttons/files/ButtonReload.png
Normal file
After Width: | Height: | Size: 643 B |
BIN
src/main/ui/buttons/files/ButtonReloadHover.png
Normal file
After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 446 B |
@ -14,6 +14,10 @@ import main.protocol.TrafficListener;
|
|||||||
import main.ui.SubForm;
|
import main.ui.SubForm;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class Connection extends SubForm {
|
public class Connection extends SubForm {
|
||||||
|
|
||||||
@ -35,8 +39,24 @@ public class Connection extends SubForm {
|
|||||||
updateInputUI();
|
updateInputUI();
|
||||||
});
|
});
|
||||||
|
|
||||||
inpPort.getItems().addAll("30000", "38101");
|
List<String> knownHosts = HConnection.autoDetectHosts;
|
||||||
inpHost.getItems().addAll("game-nl.habbo.com", "game-us.habbo.com");
|
Set<String> hosts = new HashSet<>();
|
||||||
|
Set<String> ports = new HashSet<>();
|
||||||
|
|
||||||
|
for (String h : knownHosts) {
|
||||||
|
String[] split = h.split(":");
|
||||||
|
hosts.add(split[0]);
|
||||||
|
ports.add(split[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> hostsSorted = new ArrayList<>(hosts);
|
||||||
|
hostsSorted.sort(String::compareTo);
|
||||||
|
|
||||||
|
List<String> portsSorted = new ArrayList<>(ports);
|
||||||
|
portsSorted.sort(String::compareTo);
|
||||||
|
|
||||||
|
inpPort.getItems().addAll(portsSorted);
|
||||||
|
inpHost.getItems().addAll(hostsSorted);
|
||||||
|
|
||||||
inpPort.getSelectionModel().selectFirst();
|
inpPort.getSelectionModel().selectFirst();
|
||||||
inpHost.getSelectionModel().selectFirst();
|
inpHost.getSelectionModel().selectFirst();
|
||||||
|
@ -1,17 +1,25 @@
|
|||||||
package main.ui.extensions;
|
package main.ui.extensions;
|
||||||
|
|
||||||
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.ScrollPane;
|
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import main.ui.buttons.SimpleClickButton;
|
import main.extensions.Extension;
|
||||||
|
import main.misc.ConfirmationDialog;
|
||||||
|
import main.ui.buttons.*;
|
||||||
|
import main.ui.extensions.executer.ExecutionInfo;
|
||||||
|
import main.ui.extensions.executer.ExtensionRunner;
|
||||||
|
import main.ui.extensions.executer.ExtensionRunnerFactory;
|
||||||
|
import main.ui.extensions.executer.NormalExtensionRunner;
|
||||||
import main.ui.scheduler.ScheduleItem;
|
import main.ui.scheduler.ScheduleItem;
|
||||||
import main.ui.buttons.DeleteButton;
|
|
||||||
import main.ui.buttons.EditButton;
|
import javax.tools.Tool;
|
||||||
import main.ui.buttons.PauseResumeButton;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 19/07/18.
|
* Created by Jonas on 19/07/18.
|
||||||
@ -19,17 +27,27 @@ import main.ui.buttons.PauseResumeButton;
|
|||||||
public class ExtensionItemContainer extends GridPane {
|
public class ExtensionItemContainer extends GridPane {
|
||||||
|
|
||||||
public static final int[] columnWidths = {22, 34, 18, 13, 11};
|
public static final int[] columnWidths = {22, 34, 18, 13, 11};
|
||||||
GEarthExtension item;
|
private GEarthExtension item;
|
||||||
|
|
||||||
Label titleLabel;
|
private Label titleLabel;
|
||||||
Label descriptionLabel;
|
private Label descriptionLabel;
|
||||||
Label authorLabel;
|
private Label authorLabel;
|
||||||
Label versionLabel;
|
private Label versionLabel;
|
||||||
|
|
||||||
VBox parent;
|
private VBox parent;
|
||||||
|
|
||||||
ExtensionItemContainer(GEarthExtension item, VBox parent, ScrollPane scrollPane) {
|
private volatile int port;
|
||||||
|
|
||||||
|
private HBox buttonsBox = null;
|
||||||
|
private HBox additionalButtonBox = null;
|
||||||
|
|
||||||
|
private ExitButton exitButton;
|
||||||
|
private SimpleClickButton clickButton;
|
||||||
|
private ReloadButton reloadButton;
|
||||||
|
|
||||||
|
ExtensionItemContainer(GEarthExtension item, VBox parent, ScrollPane scrollPane, int port) {
|
||||||
super();
|
super();
|
||||||
|
this.port = port;
|
||||||
setGridLinesVisible(true);
|
setGridLinesVisible(true);
|
||||||
VBox.setMargin(this, new Insets(2, -2, -2, -2));
|
VBox.setMargin(this, new Insets(2, -2, -2, -2));
|
||||||
|
|
||||||
@ -61,28 +79,72 @@ public class ExtensionItemContainer extends GridPane {
|
|||||||
add(authorLabel, 2, 0);
|
add(authorLabel, 2, 0);
|
||||||
add(versionLabel, 3, 0);
|
add(versionLabel, 3, 0);
|
||||||
|
|
||||||
// getChildren().addAll(indexLabel, packetLabel, delayLabel, destinationLabel);
|
exitButton = new ExitButton();
|
||||||
|
Tooltip delete = new Tooltip("Close connection with this extension");
|
||||||
|
Tooltip.install(exitButton,delete);
|
||||||
|
exitButton.show();
|
||||||
DeleteButton deleteButton = new DeleteButton();
|
exitButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.isRemoveClickTrigger());
|
||||||
deleteButton.show();
|
clickButton = new SimpleClickButton();
|
||||||
deleteButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.isRemoveClickTrigger());
|
|
||||||
SimpleClickButton clickButton = new SimpleClickButton();
|
|
||||||
clickButton.show();
|
clickButton.show();
|
||||||
clickButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.isClickTrigger());
|
clickButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> item.isClickTrigger());
|
||||||
|
|
||||||
HBox buttonsBox = new HBox(clickButton, deleteButton);
|
buttonsBox = new HBox(clickButton, exitButton);
|
||||||
buttonsBox.setSpacing(10);
|
|
||||||
|
reloadButton = new ReloadButton();
|
||||||
|
Tooltip reload = new Tooltip("Restart this extension");
|
||||||
|
Tooltip.install(reloadButton, reload);
|
||||||
|
reloadButton.show();
|
||||||
|
reloadButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
|
reloadButton.setVisible(false);
|
||||||
|
ExtensionRunner runner = ExtensionRunnerFactory.get();
|
||||||
|
runner.tryRunExtension(Paths.get(NormalExtensionRunner.JARPATH, ExecutionInfo.EXTENSIONSDIRECTORY, item.getFileName()).toString(), port);
|
||||||
|
});
|
||||||
|
|
||||||
|
DeleteButton deleteButton = new DeleteButton();
|
||||||
|
Tooltip uninstall = new Tooltip("Uninstall this extension");
|
||||||
|
Tooltip.install(deleteButton, uninstall);
|
||||||
|
deleteButton.show();
|
||||||
|
GridPane this2 = this;
|
||||||
|
deleteButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
|
boolean delet_dis = true;
|
||||||
|
|
||||||
|
if (ConfirmationDialog.showDialog) {
|
||||||
|
Alert alert = ConfirmationDialog.createAlertWithOptOut(Alert.AlertType.CONFIRMATION,
|
||||||
|
"Confirmation Dialog", null,
|
||||||
|
"Are you sure want to uninstall this extension?", "Do not ask again",
|
||||||
|
ButtonType.YES, ButtonType.NO
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!(alert.showAndWait().filter(t -> t == ButtonType.YES).isPresent())) {
|
||||||
|
delet_dis = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delet_dis) {
|
||||||
|
ExtensionRunner runner = ExtensionRunnerFactory.get();
|
||||||
|
runner.uninstallExtension(item.getFileName());
|
||||||
|
parent.getChildren().remove(this2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
additionalButtonBox = new HBox(reloadButton, deleteButton);
|
||||||
|
|
||||||
|
clickButton.setVisible(item.isFireButtonUsed());
|
||||||
|
exitButton.setVisible(item.isLeaveButtonVisible());
|
||||||
|
deleteButton.setVisible(item.isDeleteButtonVisible());
|
||||||
|
|
||||||
|
buttonsBox.setSpacing(8);
|
||||||
buttonsBox.setAlignment(Pos.CENTER);
|
buttonsBox.setAlignment(Pos.CENTER);
|
||||||
|
additionalButtonBox.setSpacing(8);
|
||||||
|
additionalButtonBox.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
GridPane.setMargin(buttonsBox, new Insets(0, 5, 0, 5));
|
GridPane.setMargin(buttonsBox, new Insets(0, 5, 0, 5));
|
||||||
|
GridPane.setMargin(additionalButtonBox, new Insets(0, 5, 0, 5));
|
||||||
add(buttonsBox, 4, 0);
|
add(buttonsBox, 4, 0);
|
||||||
|
|
||||||
parent.getChildren().add(this);
|
parent.getChildren().add(this);
|
||||||
|
|
||||||
|
initExtension();
|
||||||
GridPane this2 = this;
|
|
||||||
item.onDelete(observable -> parent.getChildren().remove(this2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Label initNewLabelColumn(String text) {
|
private Label initNewLabelColumn(String text) {
|
||||||
@ -92,4 +154,51 @@ public class ExtensionItemContainer extends GridPane {
|
|||||||
label.setText(text);
|
label.setText(text);
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EventHandler<MouseEvent> onExit = null;
|
||||||
|
private EventHandler<MouseEvent> onClick = null;
|
||||||
|
|
||||||
|
void initExtension(){
|
||||||
|
if (onExit != null) {
|
||||||
|
exitButton.removeEventHandler(MouseEvent.MOUSE_CLICKED, onExit);
|
||||||
|
clickButton.removeEventHandler(MouseEvent.MOUSE_CLICKED, onClick);
|
||||||
|
}
|
||||||
|
onExit = event -> item.isRemoveClickTrigger();
|
||||||
|
onClick = event -> item.isClickTrigger();
|
||||||
|
|
||||||
|
exitButton.addEventHandler(MouseEvent.MOUSE_CLICKED, onExit);
|
||||||
|
clickButton.addEventHandler(MouseEvent.MOUSE_CLICKED, onClick);
|
||||||
|
|
||||||
|
ExtensionItemContainer this2 = this;
|
||||||
|
item.onDelete(observable -> {
|
||||||
|
if (item.isInstalledExtension()) {
|
||||||
|
setBackground(new Background(new BackgroundFill(Paint.valueOf("#cccccc"),null, null)));
|
||||||
|
getChildren().remove(buttonsBox);
|
||||||
|
add(additionalButtonBox, 4, 0);
|
||||||
|
reloadButton.setVisible(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parent.getChildren().remove(this2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void hasReconnected(GEarthExtension extension) {
|
||||||
|
item = extension;
|
||||||
|
initExtension();
|
||||||
|
|
||||||
|
setBackground(new Background(new BackgroundFill(Paint.valueOf("#ffffff"),null, null)));
|
||||||
|
getChildren().remove(additionalButtonBox);
|
||||||
|
if (buttonsBox != null) {
|
||||||
|
add(buttonsBox, 4, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns null if there is none
|
||||||
|
String getExtensionFileName() {
|
||||||
|
if (item.isInstalledExtension()) {
|
||||||
|
return item.getFileName();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
45
src/main/ui/extensions/ExtensionItemContainerProducer.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package main.ui.extensions;
|
||||||
|
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.ScrollPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 27/09/18.
|
||||||
|
*/
|
||||||
|
public class ExtensionItemContainerProducer {
|
||||||
|
|
||||||
|
private VBox parent;
|
||||||
|
private ScrollPane scrollPane;
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
|
private int port = -1;
|
||||||
|
|
||||||
|
public ExtensionItemContainerProducer(VBox parent, ScrollPane scrollPane) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.scrollPane = scrollPane;
|
||||||
|
}
|
||||||
|
|
||||||
|
void extensionConnected(GEarthExtension extension) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (extension.isInstalledExtension()) {
|
||||||
|
for (Node n : parent.getChildren()) {
|
||||||
|
if (n instanceof ExtensionItemContainer) {
|
||||||
|
ExtensionItemContainer container = (ExtensionItemContainer) n;
|
||||||
|
if (container.getExtensionFileName().equals(extension.getFileName())) {
|
||||||
|
container.hasReconnected(extension);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new ExtensionItemContainer(extension, parent, scrollPane, port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -83,7 +83,7 @@
|
|||||||
<Insets left="3.0" />
|
<Insets left="3.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</Label>
|
</Label>
|
||||||
<Button fx:id="btn_install" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#installBtnClicked" text="Install" GridPane.columnIndex="3" />
|
<Button fx:id="btn_install" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#installBtnClicked" text="Install" GridPane.columnIndex="3" />
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
|
@ -9,10 +9,19 @@ import javafx.scene.control.ScrollPane;
|
|||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
import main.Main;
|
import main.Main;
|
||||||
import main.protocol.*;
|
import main.protocol.*;
|
||||||
import main.ui.SubForm;
|
import main.ui.SubForm;
|
||||||
|
import main.ui.extensions.executer.ExecutionInfo;
|
||||||
|
import main.ui.extensions.executer.ExtensionRunner;
|
||||||
|
import main.ui.extensions.executer.ExtensionRunnerFactory;
|
||||||
|
import main.ui.scheduler.ScheduleItem;
|
||||||
|
import sun.misc.ExtensionInfo;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -108,6 +117,9 @@ public class Extensions extends SubForm {
|
|||||||
public GridPane header_ext;
|
public GridPane header_ext;
|
||||||
public ScrollPane scroller;
|
public ScrollPane scroller;
|
||||||
|
|
||||||
|
private ExtensionRunner extensionRunner = null;
|
||||||
|
private GEarthExtensionsRegistrer extensionsRegistrer = null;
|
||||||
|
|
||||||
public static class OUTGOING_MESSAGES_IDS {
|
public static class OUTGOING_MESSAGES_IDS {
|
||||||
public static final int ONDOUBLECLICK = 1;
|
public static final int ONDOUBLECLICK = 1;
|
||||||
public static final int INFOREQUEST = 2; // backend: implemented
|
public static final int INFOREQUEST = 2; // backend: implemented
|
||||||
@ -138,6 +150,8 @@ public class Extensions extends SubForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void onParentSet() {
|
protected void onParentSet() {
|
||||||
|
ExtensionItemContainerProducer producer = new ExtensionItemContainerProducer(extensioncontainer, scroller);
|
||||||
|
|
||||||
getHConnection().addStateChangeListener((oldState, newState) -> {
|
getHConnection().addStateChangeListener((oldState, newState) -> {
|
||||||
if (newState == HConnection.State.CONNECTED) {
|
if (newState == HConnection.State.CONNECTED) {
|
||||||
for (GEarthExtension extension : gEarthExtensions) {
|
for (GEarthExtension extension : gEarthExtensions) {
|
||||||
@ -217,7 +231,6 @@ public class Extensions extends SubForm {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
GEarthExtensionsRegistrer extensionsRegistrer = null;
|
|
||||||
HashMap<GEarthExtension, GEarthExtension.ReceiveMessageListener> messageListeners = new HashMap<>();
|
HashMap<GEarthExtension, GEarthExtension.ReceiveMessageListener> messageListeners = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
extensionsRegistrer = new GEarthExtensionsRegistrer(new GEarthExtensionsRegistrer.ExtensionRegisterObserver() {
|
extensionsRegistrer = new GEarthExtensionsRegistrer(new GEarthExtensionsRegistrer.ExtensionRegisterObserver() {
|
||||||
@ -259,7 +272,7 @@ public class Extensions extends SubForm {
|
|||||||
if (getHConnection().getState() == HConnection.State.CONNECTED) {
|
if (getHConnection().getState() == HConnection.State.CONNECTED) {
|
||||||
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONSTART));
|
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONSTART));
|
||||||
}
|
}
|
||||||
Platform.runLater(() -> new ExtensionItemContainer(extension, extensioncontainer, scroller));
|
Platform.runLater(() -> producer.extensionConnected(extension));
|
||||||
extension.onRemoveClick(observable -> {
|
extension.onRemoveClick(observable -> {
|
||||||
try {
|
try {
|
||||||
extension.getConnection().close();
|
extension.getConnection().close();
|
||||||
@ -285,11 +298,25 @@ public class Extensions extends SubForm {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
producer.setPort(extensionsRegistrer.getPort());
|
||||||
ext_port.setText(extensionsRegistrer.getPort()+"");
|
ext_port.setText(extensionsRegistrer.getPort()+"");
|
||||||
// System.out.println("Extension server registered on port: " + extensionsRegistrer.getPort());
|
// System.out.println("Extension server registered on port: " + extensionsRegistrer.getPort());
|
||||||
|
|
||||||
|
extensionRunner = ExtensionRunnerFactory.get();
|
||||||
|
extensionRunner.runAllExtensions(extensionsRegistrer.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void installBtnClicked(ActionEvent actionEvent) {
|
public void installBtnClicked(ActionEvent actionEvent) {
|
||||||
|
List<ScheduleItem> list = new ArrayList<>();
|
||||||
|
|
||||||
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
fileChooser.setTitle("Install extension");
|
||||||
|
fileChooser.getExtensionFilters().addAll(
|
||||||
|
new FileChooser.ExtensionFilter("G-Earth extensions", ExecutionInfo.ALLOWEDEXTENSIONTYPES));
|
||||||
|
File selectedFile = fileChooser.showOpenDialog(parentController.getStage());
|
||||||
|
if (selectedFile != null) {
|
||||||
|
extensionRunner.installAndRunExtension(selectedFile.getPath(), extensionsRegistrer.getPort());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package main.ui.extensions;
|
package main.ui.extensions;
|
||||||
|
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import main.protocol.HMessage;
|
|
||||||
import main.protocol.HPacket;
|
import main.protocol.HPacket;
|
||||||
import main.protocol.packethandler.PayloadBuffer;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -24,6 +20,13 @@ public class GEarthExtension {
|
|||||||
private String version;
|
private String version;
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
private boolean fireEventButtonVisible;
|
||||||
|
private boolean leaveButtonVisible;
|
||||||
|
private boolean deleteButtonVisible;
|
||||||
|
|
||||||
|
private boolean isInstalledExtension; // <- extension is in the extensions directory
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
private Socket connection;
|
private Socket connection;
|
||||||
|
|
||||||
//calls callback when the extension is creatd
|
//calls callback when the extension is creatd
|
||||||
@ -53,10 +56,7 @@ public class GEarthExtension {
|
|||||||
|
|
||||||
if (packet.headerId() == Extensions.INCOMING_MESSAGES_IDS.EXTENSIONINFO) {
|
if (packet.headerId() == Extensions.INCOMING_MESSAGES_IDS.EXTENSIONINFO) {
|
||||||
GEarthExtension gEarthExtension = new GEarthExtension(
|
GEarthExtension gEarthExtension = new GEarthExtension(
|
||||||
packet.readString(),
|
packet,
|
||||||
packet.readString(),
|
|
||||||
packet.readString(),
|
|
||||||
packet.readString(),
|
|
||||||
connection,
|
connection,
|
||||||
onDisconnectedCallback
|
onDisconnectedCallback
|
||||||
);
|
);
|
||||||
@ -70,11 +70,19 @@ public class GEarthExtension {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private GEarthExtension(String title, String author, String version, String description, Socket connection, OnDisconnectedCallback onDisconnectedCallback) {
|
private GEarthExtension(HPacket extensionInfo, Socket connection, OnDisconnectedCallback onDisconnectedCallback) {
|
||||||
this.title = title;
|
this.title = extensionInfo.readString();
|
||||||
this.author = author;
|
this.author = extensionInfo.readString();
|
||||||
this.version = version;
|
this.version = extensionInfo.readString();
|
||||||
this.description = description;
|
this.description = extensionInfo.readString();
|
||||||
|
this.fireEventButtonVisible = extensionInfo.readBoolean();
|
||||||
|
|
||||||
|
this.isInstalledExtension = extensionInfo.readBoolean();
|
||||||
|
this.fileName = extensionInfo.readString();
|
||||||
|
|
||||||
|
this.leaveButtonVisible = extensionInfo.readBoolean();
|
||||||
|
this.deleteButtonVisible = extensionInfo.readBoolean();
|
||||||
|
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
|
||||||
GEarthExtension selff = this;
|
GEarthExtension selff = this;
|
||||||
@ -126,20 +134,31 @@ public class GEarthExtension {
|
|||||||
public String getAuthor() {
|
public String getAuthor() {
|
||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
public boolean isFireButtonUsed() {
|
||||||
|
return fireEventButtonVisible;
|
||||||
|
}
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
public boolean isDeleteButtonVisible() {
|
||||||
|
return deleteButtonVisible;
|
||||||
|
}
|
||||||
|
public boolean isLeaveButtonVisible() {
|
||||||
|
return leaveButtonVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInstalledExtension() {
|
||||||
|
return isInstalledExtension;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean closeConnection() {
|
public boolean closeConnection() {
|
||||||
try {
|
try {
|
||||||
|
39
src/main/ui/extensions/executer/ExecutionInfo.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package main.ui.extensions.executer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 22/09/18.
|
||||||
|
*/
|
||||||
|
public class ExecutionInfo {
|
||||||
|
|
||||||
|
private static Map<String, String> extensionTypeToExecutionCommand;
|
||||||
|
public final static List<String> ALLOWEDEXTENSIONTYPES;
|
||||||
|
public final static String EXTENSIONSDIRECTORY = "Extensions";
|
||||||
|
|
||||||
|
static {
|
||||||
|
extensionTypeToExecutionCommand = new HashMap<>();
|
||||||
|
extensionTypeToExecutionCommand.put("*.jar","java -jar {path}");
|
||||||
|
extensionTypeToExecutionCommand.put("*.py","python {path}");
|
||||||
|
extensionTypeToExecutionCommand.put("*.py3","python3 {path}");
|
||||||
|
extensionTypeToExecutionCommand.put("*.sh","{path}");
|
||||||
|
extensionTypeToExecutionCommand.put("*.exe","{path}");
|
||||||
|
|
||||||
|
for(String type : extensionTypeToExecutionCommand.keySet()) {
|
||||||
|
extensionTypeToExecutionCommand.put(
|
||||||
|
type,
|
||||||
|
extensionTypeToExecutionCommand.get(type) + " -p {port} -f {filename}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALLOWEDEXTENSIONTYPES = new ArrayList<>(extensionTypeToExecutionCommand.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getExecutionCommand(String type) {
|
||||||
|
return extensionTypeToExecutionCommand.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/main/ui/extensions/executer/ExtensionRunner.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package main.ui.extensions.executer;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 21/09/18.
|
||||||
|
*/
|
||||||
|
public interface ExtensionRunner {
|
||||||
|
|
||||||
|
void runAllExtensions(int port);
|
||||||
|
|
||||||
|
void installAndRunExtension(String path, int port);
|
||||||
|
|
||||||
|
void tryRunExtension(String path, int port);
|
||||||
|
|
||||||
|
void uninstallExtension(String path);
|
||||||
|
}
|
17
src/main/ui/extensions/executer/ExtensionRunnerFactory.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package main.ui.extensions.executer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 22/09/18.
|
||||||
|
*/
|
||||||
|
public class ExtensionRunnerFactory {
|
||||||
|
|
||||||
|
private static ExtensionRunner runner = obtain();
|
||||||
|
|
||||||
|
public static ExtensionRunner get() {
|
||||||
|
return runner;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ExtensionRunner obtain() {
|
||||||
|
return new NormalExtensionRunner();
|
||||||
|
}
|
||||||
|
}
|
128
src/main/ui/extensions/executer/NormalExtensionRunner.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package main.ui.extensions.executer;
|
||||||
|
|
||||||
|
import main.Main;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jonas on 22/09/18.
|
||||||
|
*/
|
||||||
|
public class NormalExtensionRunner implements ExtensionRunner {
|
||||||
|
|
||||||
|
public static final String JARPATH = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParent();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runAllExtensions(int port) {
|
||||||
|
if (dirExists(ExecutionInfo.EXTENSIONSDIRECTORY)){
|
||||||
|
File folder =
|
||||||
|
new File(JARPATH +
|
||||||
|
FileSystems.getDefault().getSeparator()+
|
||||||
|
ExecutionInfo.EXTENSIONSDIRECTORY);
|
||||||
|
|
||||||
|
File[] childs = folder.listFiles();
|
||||||
|
for (File file : childs) {
|
||||||
|
tryRunExtension(file.getPath(), port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installAndRunExtension(String path, int port) {
|
||||||
|
if (!dirExists(ExecutionInfo.EXTENSIONSDIRECTORY)) {
|
||||||
|
createDirectory(ExecutionInfo.EXTENSIONSDIRECTORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String name = Paths.get(path).getFileName().toString();
|
||||||
|
String[] split = name.split("\\.");
|
||||||
|
String ext = "*." + split[split.length - 1];
|
||||||
|
|
||||||
|
String realname = String.join(".",Arrays.copyOf(split, split.length-1));
|
||||||
|
String newname = realname + "-" + getRandomString() + ext.substring(1);
|
||||||
|
|
||||||
|
|
||||||
|
Path originalPath = Paths.get(path);
|
||||||
|
Path newPath = Paths.get(
|
||||||
|
JARPATH,
|
||||||
|
ExecutionInfo.EXTENSIONSDIRECTORY,
|
||||||
|
newname
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.copy(
|
||||||
|
originalPath,
|
||||||
|
newPath
|
||||||
|
);
|
||||||
|
|
||||||
|
addExecPermission(newPath.toString());
|
||||||
|
tryRunExtension(newPath.toString(), port);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryRunExtension(String path, int port) {
|
||||||
|
try {
|
||||||
|
Runtime.getRuntime().exec(
|
||||||
|
ExecutionInfo.getExecutionCommand(getFileExtension(path))
|
||||||
|
.replace("{path}", path)
|
||||||
|
.replace("{port}", port+"")
|
||||||
|
.replace("{filename}", Paths.get(path).getFileName().toString())
|
||||||
|
);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstallExtension(String filename) {
|
||||||
|
try {
|
||||||
|
Files.delete(Paths.get(
|
||||||
|
JARPATH,
|
||||||
|
ExecutionInfo.EXTENSIONSDIRECTORY,
|
||||||
|
filename
|
||||||
|
));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addExecPermission(String path) {
|
||||||
|
//not needed at first sight
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileExtension(String path) {
|
||||||
|
String name = Paths.get(path).getFileName().toString();
|
||||||
|
String[] split = name.split("\\.");
|
||||||
|
return "*." + split[split.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean dirExists(String dir) {
|
||||||
|
return Files.isDirectory(Paths.get(JARPATH, dir));
|
||||||
|
}
|
||||||
|
private void createDirectory(String dir) {
|
||||||
|
if (!dirExists(dir)) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(Paths.get(JARPATH, dir));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private String getRandomString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
Random r = new Random();
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
builder.append(r.nextInt(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ public class Info extends SubForm {
|
|||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
String[] lines = {
|
String[] lines = {
|
||||||
"G-Earth",
|
"G-Earth 0.1.1",
|
||||||
"Linux Habbo Packet Manipulator",
|
"Linux Habbo Packet Manipulator",
|
||||||
"",
|
"",
|
||||||
"Made by:",
|
"Made by:",
|
||||||
|
@ -8,7 +8,7 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Created by Jonas on 04/04/18.
|
* Created by Jonas on 04/04/18.
|
||||||
*/
|
*/
|
||||||
class GnomeTerminalLogger extends SimpleTerminalLogger {
|
class LinuxTerminalLogger extends SimpleTerminalLogger {
|
||||||
|
|
||||||
public final static Map<String, String> colorizePackets;
|
public final static Map<String, String> colorizePackets;
|
||||||
static {
|
static {
|
@ -1,14 +1,19 @@
|
|||||||
package main.ui.logger.loggerdisplays;
|
package main.ui.logger.loggerdisplays;
|
||||||
|
|
||||||
|
import main.misc.OSValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 04/04/18.
|
* Created by Jonas on 04/04/18.
|
||||||
*/
|
*/
|
||||||
public class PacketLoggerFactory {
|
public class PacketLoggerFactory {
|
||||||
|
|
||||||
public static PacketLogger get() {
|
public static PacketLogger get() {
|
||||||
if (System.getenv("XDG_CURRENT_DESKTOP") != null && System.getenv("XDG_CURRENT_DESKTOP").toLowerCase().contains("gnome")) {
|
if (OSValidator.isUnix()) {
|
||||||
return new GnomeTerminalLogger();
|
return new LinuxTerminalLogger();
|
||||||
}
|
}
|
||||||
|
// if (System.getenv("XDG_CURRENT_DESKTOP") != null && System.getenv("XDG_CURRENT_DESKTOP").toLowerCase().contains("gnome")) {
|
||||||
|
// return new GnomeTerminalLogger();
|
||||||
|
// }
|
||||||
return new SimpleTerminalLogger();
|
return new SimpleTerminalLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|