mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-27 02:40:51 +01:00
Work on porting stuff to javafx properties
This commit is contained in:
parent
6a9b1201ac
commit
850e89eb5e
@ -299,6 +299,12 @@
|
|||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
<version>${logback.version}</version>
|
<version>${logback.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.dustinredmond.fxtrayicon</groupId>
|
||||||
|
<artifactId>FXTrayIcon</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -1,41 +1,33 @@
|
|||||||
package gearth;
|
package gearth;
|
||||||
|
|
||||||
import gearth.misc.AdminValidator;
|
import gearth.misc.AdminValidator;
|
||||||
import gearth.misc.Cacher;
|
|
||||||
import gearth.misc.UpdateChecker;
|
import gearth.misc.UpdateChecker;
|
||||||
import gearth.misc.listenerpattern.ObservableObject;
|
|
||||||
import gearth.ui.GEarthController;
|
import gearth.ui.GEarthController;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.themes.Theme;
|
import gearth.ui.themes.Theme;
|
||||||
import gearth.ui.themes.ThemeFactory;
|
|
||||||
import gearth.ui.titlebar.TitleBarConfig;
|
import gearth.ui.titlebar.TitleBarConfig;
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class GEarth extends Application {
|
public class GEarth extends Application {
|
||||||
|
|
||||||
public static GEarth main;
|
public static GEarth main;
|
||||||
public static String version = "1.5.3";
|
public static String version = "1.5.3";
|
||||||
public static String gitApi = "https://api.github.com/repos/sirjonasxx/G-Earth/releases/latest";
|
public static String gitApi = "https://api.github.com/repos/sirjonasxx/G-Earth/releases/latest";
|
||||||
public static ObservableObject<Theme> observableTheme;
|
|
||||||
|
|
||||||
private Stage stage;
|
private Stage stage;
|
||||||
private GEarthController controller;
|
private GEarthController controller;
|
||||||
|
|
||||||
static {
|
|
||||||
observableTheme = new ObservableObject<>(
|
|
||||||
Cacher.getCacheContents().has("theme") ?
|
|
||||||
ThemeFactory.themeForTitle(Cacher.getCacheContents().getString("theme")) :
|
|
||||||
ThemeFactory.getDefaultTheme()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception{
|
public void start(Stage primaryStage) throws Exception{
|
||||||
@ -52,9 +44,28 @@ public class GEarth extends Application {
|
|||||||
}
|
}
|
||||||
controller = loader.getController();
|
controller = loader.getController();
|
||||||
controller.setStage(primaryStage);
|
controller.setStage(primaryStage);
|
||||||
stage.initStyle(StageStyle.TRANSPARENT);
|
|
||||||
|
|
||||||
|
primaryStage.initStyle(StageStyle.TRANSPARENT);
|
||||||
primaryStage.setScene(new Scene(root));
|
primaryStage.setScene(new Scene(root));
|
||||||
|
primaryStage.setAlwaysOnTop(GEarthProperties.isAlwaysOnTop());
|
||||||
|
GEarthProperties.alwaysOnTopProperty
|
||||||
|
.addListener((observable, oldValue, newValue) -> primaryStage.setAlwaysOnTop(newValue));
|
||||||
|
|
||||||
|
initTitleBar(primaryStage);
|
||||||
|
initTheme();
|
||||||
|
|
||||||
|
primaryStage.setResizable(false);
|
||||||
|
primaryStage.sizeToScene();
|
||||||
|
|
||||||
|
primaryStage.show();
|
||||||
|
primaryStage.setOnCloseRequest(event -> closeGEarth());
|
||||||
|
|
||||||
|
AdminValidator.validate();
|
||||||
|
UpdateChecker.checkForUpdates();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initTitleBar(Stage primaryStage) throws IOException {
|
||||||
TitleBarController.create(primaryStage, new TitleBarConfig() {
|
TitleBarController.create(primaryStage, new TitleBarConfig() {
|
||||||
@Override
|
@Override
|
||||||
public boolean displayThemePicker() {
|
public boolean displayThemePicker() {
|
||||||
@ -66,11 +77,6 @@ public class GEarth extends Application {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public boolean allowResizing() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCloseClicked() {
|
public void onCloseClicked() {
|
||||||
closeGEarth();
|
closeGEarth();
|
||||||
@ -83,25 +89,20 @@ public class GEarth extends Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTheme(Theme theme) {
|
public void setTheme(Theme theme) {
|
||||||
setGearthTheme(theme);
|
GEarthProperties.themeProperty.set(theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Theme getCurrentTheme() {
|
public Theme getCurrentTheme() {
|
||||||
return observableTheme.getObject();
|
return GEarthProperties.getTheme();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
primaryStage.setResizable(false);
|
}
|
||||||
primaryStage.sizeToScene();
|
|
||||||
|
|
||||||
setGearthTheme(observableTheme.getObject());
|
|
||||||
|
|
||||||
primaryStage.show();
|
|
||||||
primaryStage.setOnCloseRequest(event -> closeGEarth());
|
|
||||||
|
|
||||||
AdminValidator.validate();
|
|
||||||
UpdateChecker.checkForUpdates();
|
|
||||||
|
|
||||||
|
private void initTheme() {
|
||||||
|
stage.titleProperty().bind(GEarthProperties.themeTitleBinding);
|
||||||
|
Bindings.bindContent(stage.getScene().getStylesheets(), GEarthProperties.styleSheets);
|
||||||
|
Bindings.bindContent(stage.getIcons(), GEarthProperties.icons);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeGEarth() {
|
private void closeGEarth() {
|
||||||
@ -110,30 +111,6 @@ public class GEarth extends Application {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setGearthTheme(Theme theme) {
|
|
||||||
Cacher.put("theme", theme.title());
|
|
||||||
observableTheme.setObject(theme);
|
|
||||||
Theme defaultTheme = ThemeFactory.getDefaultTheme();
|
|
||||||
|
|
||||||
// Platform.runLater(() -> {
|
|
||||||
stage.getScene().getStylesheets().clear();
|
|
||||||
stage.getScene().getStylesheets().add(GEarth.class.getResource(String.format("/gearth/ui/themes/%s/styling.css", theme.internalName())).toExternalForm());
|
|
||||||
|
|
||||||
stage.getIcons().clear();
|
|
||||||
stage.getIcons().add(new Image(GEarth.class.getResourceAsStream(String.format("/gearth/ui/themes/%s/logoSmall.png", theme.overridesLogo() ? theme.internalName() : defaultTheme.internalName()))));
|
|
||||||
stage.setTitle((theme.overridesTitle() ? theme.title() : defaultTheme.title()) + " " + GEarth.version);
|
|
||||||
|
|
||||||
controller.infoController.img_logo.setImage(new Image(GEarth.class.getResourceAsStream(
|
|
||||||
String.format(
|
|
||||||
"/gearth/ui/themes/%s/logo.png",
|
|
||||||
theme.overridesLogo() ? theme.internalName() : defaultTheme.internalName()
|
|
||||||
)
|
|
||||||
)));
|
|
||||||
controller.infoController.version.setText(stage.getTitle());
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] args;
|
public static String[] args;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -161,14 +138,6 @@ public class GEarth extends Application {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableObject<Theme> getThemeObservable() {
|
|
||||||
return observableTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Theme getTheme() {
|
|
||||||
return observableTheme.getObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setAlertOwner(Alert alert) {
|
public static void setAlertOwner(Alert alert) {
|
||||||
alert.initOwner(main.stage);
|
alert.initOwner(main.stage);
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,14 @@ package gearth.extensions;
|
|||||||
|
|
||||||
import gearth.misc.HostInfo;
|
import gearth.misc.HostInfo;
|
||||||
import gearth.misc.listenerpattern.Observable;
|
import gearth.misc.listenerpattern.Observable;
|
||||||
import gearth.misc.listenerpattern.ObservableObject;
|
|
||||||
import gearth.protocol.HMessage;
|
import gearth.protocol.HMessage;
|
||||||
import gearth.protocol.HPacket;
|
import gearth.protocol.HPacket;
|
||||||
import gearth.services.packet_info.PacketInfo;
|
import gearth.services.packet_info.PacketInfo;
|
||||||
import gearth.services.packet_info.PacketInfoManager;
|
import gearth.services.packet_info.PacketInfoManager;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import org.reactfx.util.Lists;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public abstract class ExtensionBase extends IExtension {
|
public abstract class ExtensionBase extends IExtension {
|
||||||
|
|
||||||
@ -33,10 +28,11 @@ public abstract class ExtensionBase extends IExtension {
|
|||||||
|
|
||||||
|
|
||||||
volatile PacketInfoManager packetInfoManager = PacketInfoManager.EMPTY;
|
volatile PacketInfoManager packetInfoManager = PacketInfoManager.EMPTY;
|
||||||
ObservableObject<HostInfo> observableHostInfo = new ObservableObject<>(null);
|
|
||||||
|
ObjectProperty<HostInfo> hostInfoProperty = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
void updateHostInfo(HostInfo hostInfo) {
|
void updateHostInfo(HostInfo hostInfo) {
|
||||||
observableHostInfo.setObject(hostInfo);
|
hostInfoProperty.set(hostInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +63,7 @@ public abstract class ExtensionBase extends IExtension {
|
|||||||
* @param messageListener the callback
|
* @param messageListener the callback
|
||||||
*/
|
*/
|
||||||
public void intercept(HMessage.Direction direction, String hashOrName, MessageListener messageListener) {
|
public void intercept(HMessage.Direction direction, String hashOrName, MessageListener messageListener) {
|
||||||
Map<String, List<MessageListener>> listeners =
|
final Map<String, List<MessageListener>> listeners =
|
||||||
direction == HMessage.Direction.TOCLIENT ?
|
direction == HMessage.Direction.TOCLIENT ?
|
||||||
hashOrNameIncomingListeners :
|
hashOrNameIncomingListeners :
|
||||||
hashOrNameOutgoingListeners;
|
hashOrNameOutgoingListeners;
|
||||||
@ -197,6 +193,6 @@ public abstract class ExtensionBase extends IExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HostInfo getHostInfo() {
|
public HostInfo getHostInfo() {
|
||||||
return observableHostInfo.getObject();
|
return hostInfoProperty.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package gearth.extensions;
|
package gearth.extensions;
|
||||||
|
|
||||||
|
import com.sun.org.apache.xpath.internal.operations.Bool;
|
||||||
import gearth.misc.HostInfo;
|
import gearth.misc.HostInfo;
|
||||||
import gearth.misc.listenerpattern.Observable;
|
import gearth.misc.listenerpattern.Observable;
|
||||||
import gearth.services.packet_info.PacketInfoManager;
|
import gearth.services.packet_info.PacketInfoManager;
|
||||||
import javafx.application.HostServices;
|
import javafx.application.HostServices;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import gearth.protocol.HMessage;
|
import gearth.protocol.HMessage;
|
||||||
import gearth.protocol.HPacket;
|
import gearth.protocol.HPacket;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 22/09/18.
|
* Created by Jonas on 22/09/18.
|
||||||
*/
|
*/
|
||||||
@ -99,8 +99,17 @@ public abstract class ExtensionForm extends ExtensionBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HostInfo getHostInfo() {
|
public HostInfo getHostInfo() {
|
||||||
return extension.observableHostInfo.getObject();
|
return extension.hostInfoProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BooleanProperty fieldsInitializedProperty = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
|
public void setFieldsInitialised(boolean value) {
|
||||||
|
fieldsInitializedProperty.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty fieldsInitialisedProperty() {
|
||||||
|
return fieldsInitializedProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Observable<Runnable> fieldsInitialized = new Observable<>(Runnable::run);
|
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,8 @@ public class ExtensionFormLauncher extends Application {
|
|||||||
extensionForm.extension = extension;
|
extensionForm.extension = extension;
|
||||||
|
|
||||||
extensionForm.primaryStage = primaryStage;
|
extensionForm.primaryStage = primaryStage;
|
||||||
extensionForm.fieldsInitialized.fireEvent();
|
extensionForm.setFieldsInitialised(true);
|
||||||
|
|
||||||
Thread t = new Thread(() -> {
|
Thread t = new Thread(() -> {
|
||||||
extension.run();
|
extension.run();
|
||||||
//when the extension has ended, close this process
|
//when the extension has ended, close this process
|
||||||
|
@ -55,7 +55,7 @@ public class InternalExtensionFormLauncher<L extends InternalExtensionFormCreato
|
|||||||
extensionForm.extension = internalExtension;
|
extensionForm.extension = internalExtension;
|
||||||
extensionForm.primaryStage = stage;
|
extensionForm.primaryStage = stage;
|
||||||
|
|
||||||
extensionForm.fieldsInitialized.fireEvent();
|
extensionForm.setFieldsInitialised(true);
|
||||||
GEarthExtension gEarthExtension = new InternalExtensionBuilder(internalExtension);
|
GEarthExtension gEarthExtension = new InternalExtensionBuilder(internalExtension);
|
||||||
observer.onExtensionProduced(gEarthExtension);
|
observer.onExtensionProduced(gEarthExtension);
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ public abstract class ThemedExtensionFormCreator extends ExtensionFormCreator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ExtensionForm createForm(Stage primaryStage) throws Exception {
|
protected ExtensionForm createForm(Stage primaryStage) throws Exception {
|
||||||
FXMLLoader loader = new FXMLLoader(getFormResource());
|
final FXMLLoader loader = new FXMLLoader(getFormResource());
|
||||||
Parent root = loader.load();
|
final Parent root = loader.load();
|
||||||
|
|
||||||
primaryStage.setTitle(getTitle());
|
primaryStage.setTitle(getTitle());
|
||||||
primaryStage.setScene(new Scene(root));
|
primaryStage.setScene(new Scene(root));
|
||||||
@ -27,31 +27,38 @@ public abstract class ThemedExtensionFormCreator extends ExtensionFormCreator {
|
|||||||
primaryStage.setResizable(false);
|
primaryStage.setResizable(false);
|
||||||
primaryStage.sizeToScene();
|
primaryStage.sizeToScene();
|
||||||
|
|
||||||
Theme defaultTheme = ThemeFactory.getDefaultTheme();
|
final Theme defaultTheme = ThemeFactory.getDefaultTheme();
|
||||||
DefaultTitleBarConfig config = new DefaultTitleBarConfig(primaryStage, defaultTheme) {
|
final DefaultTitleBarConfig config = new DefaultTitleBarConfig(primaryStage, defaultTheme) {
|
||||||
@Override
|
@Override
|
||||||
public boolean displayThemePicker() {
|
public boolean displayThemePicker() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TitleBarController.create(primaryStage, config);
|
TitleBarController.create(primaryStage, config);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> primaryStage.getScene().getRoot().getStyleClass().addAll(
|
||||||
primaryStage.getScene().getRoot().getStyleClass().add(defaultTheme.title().replace(" ", "-").toLowerCase());
|
defaultTheme.title().replace(" ", "-").toLowerCase(),
|
||||||
primaryStage.getScene().getRoot().getStyleClass().add(defaultTheme.isDark() ? "g-dark" : "g-light");
|
defaultTheme.isDark() ? "g-dark" : "g-light"
|
||||||
});
|
));
|
||||||
|
|
||||||
ExtensionForm extensionForm = loader.getController();
|
final ExtensionForm extensionForm = loader.getController();
|
||||||
extensionForm.fieldsInitialized.addListener(() -> extensionForm.extension.observableHostInfo.addListener(hostInfo -> {
|
extensionForm
|
||||||
if (hostInfo.getAttributes().containsKey("theme")) {
|
.fieldsInitialisedProperty()
|
||||||
String themeTitle = hostInfo.getAttributes().get("theme");
|
.addListener(observable -> listenForThemeChange(primaryStage, config, extensionForm));
|
||||||
Theme theme = ThemeFactory.themeForTitle(themeTitle);
|
return extensionForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void listenForThemeChange(Stage primaryStage, DefaultTitleBarConfig config, ExtensionForm extensionForm) {
|
||||||
|
extensionForm.extension.hostInfoProperty.addListener((observable, oldValue, newValue) -> {
|
||||||
|
final String themeTitle = newValue.getAttributes().get("theme");
|
||||||
|
if (themeTitle != null) {
|
||||||
|
final Theme theme = ThemeFactory.themeForTitle(themeTitle);
|
||||||
if (config.getCurrentTheme() != theme) {
|
if (config.getCurrentTheme() != theme) {
|
||||||
String styleClassOld = config.getCurrentTheme().title().replace(" ", "-").toLowerCase();
|
final String styleClassOld = config.getCurrentTheme().title().replace(" ", "-").toLowerCase();
|
||||||
String lightClassOld = config.getCurrentTheme().isDark() ? "g-dark" : "g-light";
|
final String lightClassOld = config.getCurrentTheme().isDark() ? "g-dark" : "g-light";
|
||||||
String styleClassNew = theme.title().replace(" ", "-").toLowerCase();
|
final String styleClassNew = theme.title().replace(" ", "-").toLowerCase();
|
||||||
String lightClassNew = theme.isDark() ? "g-dark" : "g-light";
|
final String lightClassNew = theme.isDark() ? "g-dark" : "g-light";
|
||||||
config.setTheme(theme);
|
config.setTheme(theme);
|
||||||
Parent currentRoot = primaryStage.getScene().getRoot();
|
final Parent currentRoot = primaryStage.getScene().getRoot();
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
currentRoot.getStyleClass().remove(styleClassOld);
|
currentRoot.getStyleClass().remove(styleClassOld);
|
||||||
currentRoot.getStyleClass().add(styleClassNew);
|
currentRoot.getStyleClass().add(styleClassNew);
|
||||||
@ -62,13 +69,11 @@ public abstract class ThemedExtensionFormCreator extends ExtensionFormCreator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
|
||||||
return extensionForm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getTitle();
|
protected abstract String getTitle();
|
||||||
|
|
||||||
protected abstract URL getFormResource();
|
protected abstract URL getFormResource();
|
||||||
|
|
||||||
// can be overridden for more settings
|
// can be overridden for more settings
|
||||||
|
62
G-Earth/src/main/java/gearth/misc/BindingsUtil.java
Normal file
62
G-Earth/src/main/java/gearth/misc/BindingsUtil.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package gearth.misc;
|
||||||
|
|
||||||
|
import javafx.beans.binding.ObjectBinding;
|
||||||
|
import javafx.beans.property.IntegerProperty;
|
||||||
|
import javafx.beans.property.Property;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides utility methods for bindings.
|
||||||
|
*
|
||||||
|
* @author Dorving
|
||||||
|
*/
|
||||||
|
public final class BindingsUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the list always contains the value of the binding.
|
||||||
|
*/
|
||||||
|
public static <T> void addAndBindContent(ObservableList<T> list, ObjectBinding<T> binding) {
|
||||||
|
binding.addListener((observable, oldValue, newValue) -> {
|
||||||
|
list.remove(oldValue);
|
||||||
|
list.add(newValue);
|
||||||
|
});
|
||||||
|
list.add(binding.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a property and binds it bidirectionally to another property.
|
||||||
|
*/
|
||||||
|
public static<T> void setAndBindBiDirectional(Property<T> a, Property<T> b) {
|
||||||
|
a.setValue(b.getValue());
|
||||||
|
a.bindBidirectional(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a string property and binds it bidirectionally to another property using a converter.
|
||||||
|
*/
|
||||||
|
public static<T> void setAndBindBiDirectional(StringProperty a, Property<T> b, StringConverter<T> converter) {
|
||||||
|
a.setValue(converter.toString(b.getValue()));
|
||||||
|
a.bindBidirectional(b, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a string property and binds it bidirectionally to an integer property.
|
||||||
|
*/
|
||||||
|
public static<T> void setAndBindBiDirectional(StringProperty a, IntegerProperty b) {
|
||||||
|
setAndBindBiDirectional(a, b, STRING_INT_CONVERTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final StringConverter<Number> STRING_INT_CONVERTER = new StringConverter<Number>() {
|
||||||
|
@Override
|
||||||
|
public String toString(Number object) {
|
||||||
|
return Integer.toString(object.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Number fromString(String string) {
|
||||||
|
return Integer.parseInt(string);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
package gearth.misc;
|
package gearth.misc;
|
||||||
|
|
||||||
import gearth.GEarth;
|
import gearth.GEarth;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.Property;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@ -10,6 +14,8 @@ import java.io.IOException;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 28/09/18.
|
* Created by Jonas on 28/09/18.
|
||||||
@ -130,4 +136,36 @@ public class Cacher {
|
|||||||
public static void clear() {
|
public static void clear() {
|
||||||
clear(DEFAULT_CACHE_FILENAME);
|
clear(DEFAULT_CACHE_FILENAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <E extends Enum<E>> void ifEnumPresent(String key, Class<E> enumClass, Consumer<E> consumer) {
|
||||||
|
if (getCacheContents().has(key)) {
|
||||||
|
final E value = getCacheContents().getEnum(enumClass, key);
|
||||||
|
consumer.accept(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static <E extends Enum<E>> void bindEnum(String key, Class<E> enumClass, ObjectProperty<E> valueProperty) {
|
||||||
|
if (getCacheContents().has(key)) {
|
||||||
|
final E value = getCacheContents().getEnum(enumClass, key);
|
||||||
|
valueProperty.set(value);
|
||||||
|
}
|
||||||
|
valueProperty.addListener((observable, oldValue, newValue) -> put(key, newValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindString(String key, StringProperty valueProperty) {
|
||||||
|
bind(key, valueProperty, getCacheContents()::getString);
|
||||||
|
}
|
||||||
|
public static void bindNumber(String key, Property<Number> valueProperty) {
|
||||||
|
bind(key, valueProperty, getCacheContents()::getNumber);
|
||||||
|
}
|
||||||
|
public static void bindBoolean(String key, BooleanProperty valueProperty) {
|
||||||
|
bind(key, valueProperty, getCacheContents()::getBoolean);
|
||||||
|
}
|
||||||
|
public static void bindJSONObject(String key, ObjectProperty<JSONObject> valueProperty) {
|
||||||
|
bind(key, valueProperty, getCacheContents()::getJSONObject);
|
||||||
|
}
|
||||||
|
private static <T> void bind(String key, Property<T> valueProperty, Function<String, T> reader) {
|
||||||
|
if (getCacheContents().has(key))
|
||||||
|
valueProperty.setValue(reader.apply(key));
|
||||||
|
valueProperty.addListener((observable, oldValue, newValue) -> put(key, newValue));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
package gearth.misc.listenerpattern;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class ObservableObject<T> extends Observable<Consumer<T>> {
|
|
||||||
|
|
||||||
private T object;
|
|
||||||
|
|
||||||
public ObservableObject(T object) {
|
|
||||||
super();
|
|
||||||
this.object = object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObject(T object) {
|
|
||||||
this.object = object;
|
|
||||||
fireEvent(c -> c.accept(object));
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getObject() {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,29 +13,29 @@ import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
|||||||
import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
|
import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
|
||||||
import gearth.protocol.connection.proxy.unity.UnityProxyProvider;
|
import gearth.protocol.connection.proxy.unity.UnityProxyProvider;
|
||||||
import gearth.services.extension_handler.ExtensionHandler;
|
import gearth.services.extension_handler.ExtensionHandler;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class HConnection {
|
public class HConnection {
|
||||||
|
|
||||||
public static volatile boolean DECRYPTPACKETS = true;
|
|
||||||
public static volatile boolean DEBUG = false;
|
|
||||||
|
|
||||||
private volatile ExtensionHandler extensionHandler = null;
|
private volatile ExtensionHandler extensionHandler = null;
|
||||||
|
|
||||||
private volatile Object[] trafficObservables = {new Observable<TrafficListener>(), new Observable<TrafficListener>(), new Observable<TrafficListener>()};
|
private volatile Object[] trafficObservables = {new Observable<TrafficListener>(), new Observable<TrafficListener>(), new Observable<TrafficListener>()};
|
||||||
private volatile Observable<StateChangeListener> stateObservable = new Observable<>();
|
|
||||||
private volatile Observable<Consumer<Boolean>> developerModeChangeObservable = new Observable<>();
|
|
||||||
|
|
||||||
private volatile HState state = HState.NOT_CONNECTED;
|
@Deprecated
|
||||||
|
private volatile Observable<StateChangeListener> stateObservable = new Observable<>();
|
||||||
|
|
||||||
|
private final ObjectProperty<HState> stateProperty = new SimpleObjectProperty<>(HState.NOT_CONNECTED);
|
||||||
|
|
||||||
private volatile HProxy proxy = null;
|
private volatile HProxy proxy = null;
|
||||||
|
|
||||||
private ProxyProviderFactory proxyProviderFactory;
|
private ProxyProviderFactory proxyProviderFactory;
|
||||||
private ProxyProvider proxyProvider = null;
|
private ProxyProvider proxyProvider = null;
|
||||||
|
|
||||||
private volatile boolean developerMode = false;
|
|
||||||
|
|
||||||
public HConnection() {
|
public HConnection() {
|
||||||
HConnection selff = this;
|
HConnection selff = this;
|
||||||
proxyProviderFactory = new ProxyProviderFactory(
|
proxyProviderFactory = new ProxyProviderFactory(
|
||||||
@ -47,16 +47,16 @@ public class HConnection {
|
|||||||
PacketSafetyManager.PACKET_SAFETY_MANAGER.initialize(this);
|
PacketSafetyManager.PACKET_SAFETY_MANAGER.initialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObjectProperty<HState> stateProperty() {
|
||||||
|
return stateProperty;
|
||||||
|
}
|
||||||
|
|
||||||
public HState getState() {
|
public HState getState() {
|
||||||
return state;
|
return stateProperty.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setState(HState state) {
|
private void setState(HState state) {
|
||||||
if (state != this.state) {
|
stateProperty.set(state);
|
||||||
HState buffer = this.state;
|
|
||||||
this.state = state;
|
|
||||||
stateObservable.fireEvent(l -> l.stateChanged(buffer, state));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// autodetect mode
|
// autodetect mode
|
||||||
@ -107,6 +107,7 @@ public class HConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Observable<StateChangeListener> getStateObservable() {
|
public Observable<StateChangeListener> getStateObservable() {
|
||||||
return stateObservable;
|
return stateObservable;
|
||||||
}
|
}
|
||||||
@ -165,11 +166,12 @@ public class HConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canSendPacket(HMessage.Direction direction, HPacket packet) {
|
public boolean canSendPacket(HMessage.Direction direction, HPacket packet) {
|
||||||
return isPacketSendingAllowed(direction, packet) && (developerMode || isPacketSendingSafe(direction, packet));
|
return isPacketSendingAllowed(direction, packet)
|
||||||
|
&& (GEarthProperties.isDeveloperModeEnabled() || isPacketSendingSafe(direction, packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPacketSendingAllowed(HMessage.Direction direction, HPacket packet) {
|
public boolean isPacketSendingAllowed(HMessage.Direction direction, HPacket packet) {
|
||||||
if (state != HState.CONNECTED) return false;
|
if (getState() != HState.CONNECTED) return false;
|
||||||
|
|
||||||
HProxy proxy = this.proxy;
|
HProxy proxy = this.proxy;
|
||||||
if (proxy == null) return false;
|
if (proxy == null) return false;
|
||||||
@ -196,14 +198,6 @@ public class HConnection {
|
|||||||
return packetsContainer.isPacketSafe(packet.headerId(), direction);
|
return packetsContainer.isPacketSafe(packet.headerId(), direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeveloperMode(boolean developerMode) {
|
|
||||||
this.developerMode = developerMode;
|
|
||||||
developerModeChangeObservable.fireEvent(listener -> listener.accept(developerMode));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onDeveloperModeChange(Consumer<Boolean> onChange) {
|
|
||||||
developerModeChangeObservable.addListener(onChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientHost() {
|
public String getClientHost() {
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
|
@ -10,15 +10,14 @@ import gearth.protocol.memory.Rc4Obtainer;
|
|||||||
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
|
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
|
||||||
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
|
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
|
||||||
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.stage.Stage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@ -47,7 +46,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
|||||||
client.setSoTimeout(0);
|
client.setSoTimeout(0);
|
||||||
server.setSoTimeout(0);
|
server.setSoTimeout(0);
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
|
||||||
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
|
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
|
||||||
|
|
||||||
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
|
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
|
||||||
@ -73,7 +72,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
|||||||
try {
|
try {
|
||||||
if (!server.isClosed()) server.close();
|
if (!server.isClosed()) server.close();
|
||||||
if (!client.isClosed()) client.close();
|
if (!client.isClosed()) client.close();
|
||||||
if (HConnection.DEBUG) System.out.println("STOP");
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("STOP");
|
||||||
if (datastream[0]) {
|
if (datastream[0]) {
|
||||||
onConnectEnd();
|
onConnectEnd();
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package gearth.protocol.connection.proxy.flash;
|
package gearth.protocol.connection.proxy.flash;
|
||||||
|
|
||||||
import gearth.GEarth;
|
|
||||||
import gearth.misc.Cacher;
|
import gearth.misc.Cacher;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.connection.*;
|
import gearth.protocol.connection.*;
|
||||||
@ -10,12 +9,11 @@ import gearth.protocol.hostreplacer.hostsfile.HostReplacer;
|
|||||||
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
|
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
|
||||||
import gearth.protocol.portchecker.PortChecker;
|
import gearth.protocol.portchecker.PortChecker;
|
||||||
import gearth.protocol.portchecker.PortCheckerFactory;
|
import gearth.protocol.portchecker.PortCheckerFactory;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
@ -128,7 +126,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
Socket client = proxy_server.accept();
|
Socket client = proxy_server.accept();
|
||||||
proxy = potentialProxy;
|
proxy = potentialProxy;
|
||||||
closeAllProxies(proxy);
|
closeAllProxies(proxy);
|
||||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("accepted a proxy");
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
@ -173,7 +171,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println("done waiting for clients with: " + hConnection.getState() );
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("done waiting for clients with: " + hConnection.getState() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
|||||||
import gearth.protocol.connection.proxy.SocksConfiguration;
|
import gearth.protocol.connection.proxy.SocksConfiguration;
|
||||||
import gearth.protocol.hostreplacer.ipmapping.IpMapper;
|
import gearth.protocol.hostreplacer.ipmapping.IpMapper;
|
||||||
import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory;
|
import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
@ -54,7 +55,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
|
|
||||||
maybeAddMapping();
|
maybeAddMapping();
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println("Added mapping for raw IP");
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("Added mapping for raw IP");
|
||||||
|
|
||||||
ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
|
ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
|
||||||
proxy.initProxy(proxy_server);
|
proxy.initProxy(proxy_server);
|
||||||
@ -62,10 +63,10 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
||||||
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||||
try {
|
try {
|
||||||
if (HConnection.DEBUG) System.out.println("try accept proxy");
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("try accept proxy");
|
||||||
Socket client = proxy_server.accept();
|
Socket client = proxy_server.accept();
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("accepted a proxy");
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
@ -151,7 +152,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
createSocksProxyThread(client);
|
createSocksProxyThread(client);
|
||||||
}
|
}
|
||||||
else if (preConnectedServerConnections.isEmpty()) {
|
else if (preConnectedServerConnections.isEmpty()) {
|
||||||
if (HConnection.DEBUG) System.out.println("pre-made server connections ran out of stock");
|
if (GEarthProperties.isDebugModeEnabled()) System.out.println("pre-made server connections ran out of stock");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
startProxyThread(client, preConnectedServerConnections.poll(), proxy);
|
startProxyThread(client, preConnectedServerConnections.poll(), proxy);
|
||||||
|
@ -9,6 +9,8 @@ import gearth.protocol.connection.proxy.ProxyProvider;
|
|||||||
import gearth.protocol.connection.proxy.nitro.http.NitroHttpProxy;
|
import gearth.protocol.connection.proxy.nitro.http.NitroHttpProxy;
|
||||||
import gearth.protocol.connection.proxy.nitro.http.NitroHttpProxyServerCallback;
|
import gearth.protocol.connection.proxy.nitro.http.NitroHttpProxyServerCallback;
|
||||||
import gearth.protocol.connection.proxy.nitro.websocket.NitroWebsocketProxy;
|
import gearth.protocol.connection.proxy.nitro.websocket.NitroWebsocketProxy;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ import java.io.IOException;
|
|||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCallback, StateChangeListener {
|
public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCallback, ChangeListener<HState> {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(NitroProxyProvider.class);
|
private static final Logger logger = LoggerFactory.getLogger(NitroProxyProvider.class);
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCa
|
|||||||
originalWebsocketUrl = null;
|
originalWebsocketUrl = null;
|
||||||
originalCookies = null;
|
originalCookies = null;
|
||||||
|
|
||||||
connection.getStateObservable().addListener(this);
|
connection.stateProperty().addListener(this);
|
||||||
|
|
||||||
logger.info("Starting http proxy");
|
logger.info("Starting http proxy");
|
||||||
|
|
||||||
@ -112,7 +114,7 @@ public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCa
|
|||||||
|
|
||||||
stateSetter.setState(HState.NOT_CONNECTED);
|
stateSetter.setState(HState.NOT_CONNECTED);
|
||||||
|
|
||||||
connection.getStateObservable().removeListener(this);
|
connection.stateProperty().removeListener(this);
|
||||||
|
|
||||||
logger.info("Nitro proxy stopped");
|
logger.info("Nitro proxy stopped");
|
||||||
}).start();
|
}).start();
|
||||||
@ -131,16 +133,15 @@ public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(HState oldState, HState newState) {
|
public void changed(ObservableValue<? extends HState> observable, HState oldValue, HState newValue) {
|
||||||
if (oldState == HState.WAITING_FOR_CLIENT && newState == HState.CONNECTED) {
|
if (oldValue == HState.WAITING_FOR_CLIENT && newValue == HState.CONNECTED) {
|
||||||
// Unregister but do not stop http proxy.
|
// Unregister but do not stop http proxy.
|
||||||
// We are not stopping the http proxy because some requests might still require it to be running.
|
// We are not stopping the http proxy because some requests might still require it to be running.
|
||||||
nitroHttpProxy.pause();
|
nitroHttpProxy.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catch setState ABORTING inside NitroWebsocketClient.
|
// Catch setState ABORTING inside NitroWebsocketClient.
|
||||||
if (newState == HState.ABORTING) {
|
if (newValue == HState.ABORTING)
|
||||||
abort();
|
abort();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
package gearth.protocol.connection.proxy.unity;
|
package gearth.protocol.connection.proxy.unity;
|
||||||
|
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.StateChangeListener;
|
|
||||||
import gearth.protocol.connection.HProxySetter;
|
import gearth.protocol.connection.HProxySetter;
|
||||||
import gearth.protocol.connection.HState;
|
import gearth.protocol.connection.HState;
|
||||||
import gearth.protocol.connection.HStateSetter;
|
import gearth.protocol.connection.HStateSetter;
|
||||||
import gearth.protocol.connection.proxy.ProxyProvider;
|
import gearth.protocol.connection.proxy.ProxyProvider;
|
||||||
import gearth.services.unity_tools.GUnityFileServer;
|
import gearth.services.unity_tools.GUnityFileServer;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.websocket.server.ServerContainer;
|
import javax.websocket.server.ServerContainer;
|
||||||
import javax.websocket.server.ServerEndpointConfig;
|
import javax.websocket.server.ServerEndpointConfig;
|
||||||
@ -22,6 +25,9 @@ import static gearth.services.unity_tools.GUnityFileServer.FILESERVER_PORT;
|
|||||||
|
|
||||||
public class UnityProxyProvider implements ProxyProvider {
|
public class UnityProxyProvider implements ProxyProvider {
|
||||||
|
|
||||||
|
private final static Logger LOGGER = LoggerFactory.getLogger(UnityProxyProvider.class);
|
||||||
|
|
||||||
|
public static final int PORT_REQUESTER_SERVER_PORT = 9039;
|
||||||
private final HProxySetter proxySetter;
|
private final HProxySetter proxySetter;
|
||||||
private final HStateSetter stateSetter;
|
private final HStateSetter stateSetter;
|
||||||
private final HConnection hConnection;
|
private final HConnection hConnection;
|
||||||
@ -34,7 +40,6 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
this.hConnection = hConnection;
|
this.hConnection = hConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws IOException {
|
public void start() throws IOException {
|
||||||
// https://happyhyppo.ro/2016/03/21/minimal-websockets-communication-with-javajetty-and-angularjs/
|
// https://happyhyppo.ro/2016/03/21/minimal-websockets-communication-with-javajetty-and-angularjs/
|
||||||
@ -45,13 +50,13 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
while (fail && port < 9100) {
|
while (fail && port < 9100) {
|
||||||
try {
|
try {
|
||||||
packetHandlerServer = new Server(port);
|
packetHandlerServer = new Server(port);
|
||||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
context.setContextPath("/ws");
|
context.setContextPath("/ws");
|
||||||
|
|
||||||
HandlerList handlers = new HandlerList();
|
final HandlerList handlers = new HandlerList();
|
||||||
handlers.setHandlers(new Handler[] { context });
|
handlers.setHandlers(new Handler[] { context });
|
||||||
|
|
||||||
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
final ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
||||||
wscontainer.addEndpoint(ServerEndpointConfig.Builder
|
wscontainer.addEndpoint(ServerEndpointConfig.Builder
|
||||||
.create(UnityCommunicator.class, "/packethandler") // the endpoint url
|
.create(UnityCommunicator.class, "/packethandler") // the endpoint url
|
||||||
.configurator(new UnityCommunicatorConfig(proxySetter, stateSetter, hConnection, this))
|
.configurator(new UnityCommunicatorConfig(proxySetter, stateSetter, hConnection, this))
|
||||||
@ -65,10 +70,8 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fail) {
|
if (fail)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
startPortRequestServer(port);
|
startPortRequestServer(port);
|
||||||
startUnityFileServer();
|
startUnityFileServer();
|
||||||
@ -79,17 +82,16 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
try {
|
try {
|
||||||
packetHandlerServer.stop();
|
packetHandlerServer.stop();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LOGGER.error("Failed to close packet handler server", ex);
|
||||||
}
|
}
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to connect to unity proxy", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void abort() {
|
public synchronized void abort() {
|
||||||
if (packetHandlerServer == null) {
|
if (packetHandlerServer == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
final Server abortThis = packetHandlerServer;
|
final Server abortThis = packetHandlerServer;
|
||||||
stateSetter.setState(HState.ABORTING);
|
stateSetter.setState(HState.ABORTING);
|
||||||
@ -97,7 +99,7 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
try {
|
try {
|
||||||
abortThis.stop();
|
abortThis.stop();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to abort", e);
|
||||||
} finally {
|
} finally {
|
||||||
stateSetter.setState(HState.NOT_CONNECTED);
|
stateSetter.setState(HState.NOT_CONNECTED);
|
||||||
}
|
}
|
||||||
@ -106,43 +108,30 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startUnityFileServer() throws Exception {
|
private void startUnityFileServer() throws Exception {
|
||||||
Server server = new Server(FILESERVER_PORT);
|
final Server server = new Server(FILESERVER_PORT);
|
||||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
context.setContextPath("/");
|
context.setContextPath("/");
|
||||||
|
|
||||||
context.addServlet(new ServletHolder(new GUnityFileServer()), "/*");
|
context.addServlet(new ServletHolder(new GUnityFileServer()), "/*");
|
||||||
|
|
||||||
HandlerList handlers = new HandlerList();
|
final HandlerList handlers = new HandlerList();
|
||||||
handlers.setHandlers(new Handler[] { context });
|
handlers.setHandlers(new Handler[] { context });
|
||||||
server.setHandler(handlers);
|
server.setHandler(handlers);
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
StateChangeListener fileServerCloser = new StateChangeListener() {
|
|
||||||
@Override
|
stopServerOnDisconnect(server);
|
||||||
public void stateChanged(HState oldState, HState newState) {
|
|
||||||
if (oldState == HState.WAITING_FOR_CLIENT || newState == HState.NOT_CONNECTED) {
|
|
||||||
hConnection.getStateObservable().removeListener(this);
|
|
||||||
try {
|
|
||||||
server.stop();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
hConnection.getStateObservable().addListener(fileServerCloser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startPortRequestServer(int packetHandlerPort) throws Exception {
|
private void startPortRequestServer(int packetHandlerPort) throws Exception {
|
||||||
Server portRequestServer = new Server(9039);
|
final Server portRequestServer = new Server(PORT_REQUESTER_SERVER_PORT);
|
||||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
context.setContextPath("/ws");
|
context.setContextPath("/ws");
|
||||||
|
|
||||||
HandlerList handlers = new HandlerList();
|
final HandlerList handlers = new HandlerList();
|
||||||
handlers.setHandlers(new Handler[] { context });
|
handlers.setHandlers(new Handler[] { context });
|
||||||
portRequestServer.setHandler(handlers);
|
portRequestServer.setHandler(handlers);
|
||||||
|
|
||||||
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
final ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
||||||
wscontainer.addEndpoint(ServerEndpointConfig.Builder
|
wscontainer.addEndpoint(ServerEndpointConfig.Builder
|
||||||
.create(PortRequester.class, "/portrequest") // the endpoint url
|
.create(PortRequester.class, "/portrequest") // the endpoint url
|
||||||
.configurator(new PortRequesterConfig(packetHandlerPort))
|
.configurator(new PortRequesterConfig(packetHandlerPort))
|
||||||
@ -150,19 +139,22 @@ public class UnityProxyProvider implements ProxyProvider {
|
|||||||
|
|
||||||
portRequestServer.start();
|
portRequestServer.start();
|
||||||
|
|
||||||
StateChangeListener portRequesterCloser = new StateChangeListener() {
|
stopServerOnDisconnect(portRequestServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopServerOnDisconnect(Server server) {
|
||||||
|
hConnection.stateProperty().addListener(new ChangeListener<HState>() {
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(HState oldState, HState newState) {
|
public void changed(ObservableValue<? extends HState> observable, HState oldValue, HState newValue) {
|
||||||
if (oldState == HState.WAITING_FOR_CLIENT || newState == HState.NOT_CONNECTED) {
|
if (oldValue == HState.WAITING_FOR_CLIENT || newValue == HState.NOT_CONNECTED) {
|
||||||
hConnection.getStateObservable().removeListener(this);
|
hConnection.stateProperty().removeListener(this);
|
||||||
try {
|
try {
|
||||||
portRequestServer.stop();
|
server.stop();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to stop server {}", server, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
hConnection.getStateObservable().addListener(portRequesterCloser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@ import gearth.protocol.crypto.RC4;
|
|||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
import gearth.protocol.memory.habboclient.HabboClient;
|
||||||
import gearth.protocol.memory.habboclient.HabboClientFactory;
|
import gearth.protocol.memory.habboclient.HabboClientFactory;
|
||||||
import gearth.protocol.packethandler.PayloadBuffer;
|
import gearth.protocol.packethandler.PayloadBuffer;
|
||||||
import gearth.protocol.packethandler.flash.BufferChangeListener;
|
|
||||||
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.InvalidationListener;
|
||||||
|
import javafx.beans.Observable;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
import javafx.scene.control.Hyperlink;
|
import javafx.scene.control.Hyperlink;
|
||||||
@ -37,21 +39,22 @@ public class Rc4Obtainer {
|
|||||||
public void setFlashPacketHandlers(FlashPacketHandler... flashPacketHandlers) {
|
public void setFlashPacketHandlers(FlashPacketHandler... flashPacketHandlers) {
|
||||||
this.flashPacketHandlers = Arrays.asList(flashPacketHandlers);
|
this.flashPacketHandlers = Arrays.asList(flashPacketHandlers);
|
||||||
for (FlashPacketHandler handler : flashPacketHandlers) {
|
for (FlashPacketHandler handler : flashPacketHandlers) {
|
||||||
BufferChangeListener bufferChangeListener = new BufferChangeListener() {
|
final InvalidationListener bufferChangeListener = new InvalidationListener() {
|
||||||
@Override
|
@Override
|
||||||
public void act() {
|
public void invalidated(Observable observable) {
|
||||||
if (handler.isEncryptedStream()) {
|
if (handler.isEncryptedStream()) {
|
||||||
onSendFirstEncryptedMessage(handler);
|
Rc4Obtainer.this.onSendFirstEncryptedMessage(handler);
|
||||||
handler.getBufferChangeObservable().removeListener(this);
|
handler.incomingBufferProperty().removeListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
handler.getBufferChangeObservable().addListener(bufferChangeListener);
|
handler.incomingBufferProperty().addListener(bufferChangeListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler) {
|
private void onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler) {
|
||||||
if (!HConnection.DECRYPTPACKETS) return;
|
if (GEarthProperties.isPacketDecryptionDisabled())
|
||||||
|
return;
|
||||||
|
|
||||||
flashPacketHandlers.forEach(FlashPacketHandler::block);
|
flashPacketHandlers.forEach(FlashPacketHandler::block);
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package gearth.protocol.packethandler.flash;
|
|
||||||
|
|
||||||
|
|
||||||
public interface BufferChangeListener {
|
|
||||||
|
|
||||||
void act();
|
|
||||||
|
|
||||||
}
|
|
@ -1,13 +1,14 @@
|
|||||||
package gearth.protocol.packethandler.flash;
|
package gearth.protocol.packethandler.flash;
|
||||||
|
|
||||||
import gearth.misc.listenerpattern.Observable;
|
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.protocol.HMessage;
|
import gearth.protocol.HMessage;
|
||||||
import gearth.protocol.HPacket;
|
import gearth.protocol.HPacket;
|
||||||
import gearth.protocol.crypto.RC4;
|
import gearth.protocol.crypto.RC4;
|
||||||
import gearth.protocol.packethandler.PacketHandler;
|
import gearth.protocol.packethandler.PacketHandler;
|
||||||
import gearth.protocol.packethandler.PayloadBuffer;
|
import gearth.protocol.packethandler.PayloadBuffer;
|
||||||
import gearth.services.extension_handler.ExtensionHandler;
|
import gearth.services.extension_handler.ExtensionHandler;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -18,7 +19,7 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
|||||||
|
|
||||||
protected static final boolean DEBUG = false;
|
protected static final boolean DEBUG = false;
|
||||||
|
|
||||||
private volatile OutputStream out;
|
private final OutputStream out;
|
||||||
private volatile boolean isTempBlocked = false;
|
private volatile boolean isTempBlocked = false;
|
||||||
volatile boolean isDataStream = false;
|
volatile boolean isDataStream = false;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
|||||||
FlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
|
FlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
|
||||||
super(extensionHandler, trafficObservables);
|
super(extensionHandler, trafficObservables);
|
||||||
out = outputStream;
|
out = outputStream;
|
||||||
this.payloadBuffer = new PayloadBuffer();
|
payloadBuffer = new PayloadBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDataStream() {return isDataStream;}
|
public boolean isDataStream() {return isDataStream;}
|
||||||
@ -49,6 +50,7 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void act(byte[] buffer) throws IOException {
|
public void act(byte[] buffer) throws IOException {
|
||||||
|
|
||||||
if (!isDataStream) {
|
if (!isDataStream) {
|
||||||
synchronized (sendLock) {
|
synchronized (sendLock) {
|
||||||
out.write(buffer);
|
out.write(buffer);
|
||||||
@ -56,20 +58,19 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferChangeObservable.fireEvent();
|
incomingBufferProperty.set(buffer);
|
||||||
|
|
||||||
if (!isEncryptedStream) {
|
if (!isEncryptedStream) {
|
||||||
payloadBuffer.push(buffer);
|
payloadBuffer.push(buffer);
|
||||||
}
|
}
|
||||||
else if (!HConnection.DECRYPTPACKETS) {
|
else if (GEarthProperties.isPacketDecryptionDisabled()) {
|
||||||
synchronized (sendLock) {
|
synchronized (sendLock) {
|
||||||
out.write(buffer);
|
out.write(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (decryptcipher == null) {
|
else if (decryptcipher == null) {
|
||||||
for (int i = 0; i < buffer.length; i++) {
|
for (byte b : buffer)
|
||||||
tempEncryptedBuffer.add(buffer[i]);
|
tempEncryptedBuffer.add(b);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
byte[] tm = decryptcipher.rc4(buffer);
|
byte[] tm = decryptcipher.rc4(buffer);
|
||||||
@ -162,9 +163,10 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
|||||||
|
|
||||||
protected abstract void printForDebugging(byte[] bytes);
|
protected abstract void printForDebugging(byte[] bytes);
|
||||||
|
|
||||||
private Observable<BufferChangeListener> bufferChangeObservable = new Observable<>(BufferChangeListener::act);
|
private final ObjectProperty<byte[]> incomingBufferProperty = new SimpleObjectProperty<>();
|
||||||
public Observable<BufferChangeListener> getBufferChangeObservable() {
|
|
||||||
return bufferChangeObservable;
|
public ObjectProperty<byte[]> incomingBufferProperty() {
|
||||||
|
return incomingBufferProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentIndex() {
|
public int getCurrentIndex() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package gearth.services.extension_handler;
|
package gearth.services.extension_handler;
|
||||||
|
|
||||||
import gearth.GEarth;
|
import gearth.GEarth;
|
||||||
import gearth.misc.HostInfo;
|
|
||||||
import gearth.misc.listenerpattern.Observable;
|
import gearth.misc.listenerpattern.Observable;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.HMessage;
|
import gearth.protocol.HMessage;
|
||||||
@ -12,14 +11,15 @@ import gearth.services.extension_handler.extensions.GEarthExtension;
|
|||||||
import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducer;
|
import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducer;
|
||||||
import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducerFactory;
|
import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducerFactory;
|
||||||
import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducerObserver;
|
import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducerObserver;
|
||||||
import gearth.ui.themes.Theme;
|
import gearth.ui.GEarthProperties;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.util.Pair;
|
import javafx.util.Pair;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class ExtensionHandler {
|
public class ExtensionHandler implements ChangeListener<HState> {
|
||||||
|
|
||||||
private final List<GEarthExtension> gEarthExtensions = new ArrayList<>();
|
private final List<GEarthExtension> gEarthExtensions = new ArrayList<>();
|
||||||
private final HConnection hConnection;
|
private final HConnection hConnection;
|
||||||
@ -47,38 +47,13 @@ public class ExtensionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
GEarth.getThemeObservable().addListener(theme -> {
|
GEarthProperties.hostInfoBinding.addListener(((observable1, oldValue, newValue) -> {
|
||||||
synchronized (gEarthExtensions) {
|
synchronized (gEarthExtensions) {
|
||||||
for (GEarthExtension extension : gEarthExtensions) {
|
gEarthExtensions.forEach(extension -> extension.updateHostInfo(newValue));
|
||||||
extension.updateHostInfo(getHostInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
hConnection.getStateObservable().addListener((oldState, newState) -> {
|
|
||||||
if (newState == HState.CONNECTED) {
|
|
||||||
synchronized (gEarthExtensions) {
|
|
||||||
for (GEarthExtension extension : gEarthExtensions) {
|
|
||||||
extension.connectionStart(
|
|
||||||
hConnection.getDomain(),
|
|
||||||
hConnection.getServerPort(),
|
|
||||||
hConnection.getHotelVersion(),
|
|
||||||
hConnection.getClientIdentifier(),
|
|
||||||
hConnection.getClientType(),
|
|
||||||
hConnection.getPacketInfoManager()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (oldState == HState.CONNECTED) {
|
|
||||||
synchronized (gEarthExtensions) {
|
|
||||||
for (GEarthExtension extension : gEarthExtensions) {
|
|
||||||
extension.connectionEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
hConnection.stateProperty().addListener(this);
|
||||||
extensionProducers = ExtensionProducerFactory.getAll();
|
extensionProducers = ExtensionProducerFactory.getAll();
|
||||||
extensionProducers.forEach(extensionProducer -> extensionProducer.startProducing(createExtensionProducerObserver()));
|
extensionProducers.forEach(extensionProducer -> extensionProducer.startProducing(createExtensionProducerObserver()));
|
||||||
}
|
}
|
||||||
@ -259,7 +234,7 @@ public class ExtensionHandler {
|
|||||||
extension.getClickedObservable().addListener(extension::doubleclick);
|
extension.getClickedObservable().addListener(extension::doubleclick);
|
||||||
observable.fireEvent(l -> l.onExtensionConnect(extension));
|
observable.fireEvent(l -> l.onExtensionConnect(extension));
|
||||||
|
|
||||||
extension.init(hConnection.getState() == HState.CONNECTED, getHostInfo());
|
extension.init(hConnection.getState() == HState.CONNECTED, GEarthProperties.getHostInfo());
|
||||||
if (hConnection.getState() == HState.CONNECTED) {
|
if (hConnection.getState() == HState.CONNECTED) {
|
||||||
extension.connectionStart(
|
extension.connectionStart(
|
||||||
hConnection.getDomain(),
|
hConnection.getDomain(),
|
||||||
@ -274,16 +249,6 @@ public class ExtensionHandler {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private HostInfo getHostInfo() {
|
|
||||||
HashMap<String, String> attributes = new HashMap<>();
|
|
||||||
attributes.put("theme", GEarth.getTheme().title());
|
|
||||||
return new HostInfo(
|
|
||||||
"G-Earth",
|
|
||||||
GEarth.version,
|
|
||||||
attributes
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtensionProducer> getExtensionProducers() {
|
public List<ExtensionProducer> getExtensionProducers() {
|
||||||
return extensionProducers;
|
return extensionProducers;
|
||||||
}
|
}
|
||||||
@ -296,5 +261,26 @@ public class ExtensionHandler {
|
|||||||
extensionProducers.add(producer);
|
extensionProducers.add(producer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends HState> observable, HState oldValue, HState newValue) {
|
||||||
|
if (newValue == HState.CONNECTED) {
|
||||||
|
synchronized (gEarthExtensions) {
|
||||||
|
for (GEarthExtension extension : gEarthExtensions) {
|
||||||
|
extension.connectionStart(
|
||||||
|
hConnection.getDomain(),
|
||||||
|
hConnection.getServerPort(),
|
||||||
|
hConnection.getHotelVersion(),
|
||||||
|
hConnection.getClientIdentifier(),
|
||||||
|
hConnection.getClientType(),
|
||||||
|
hConnection.getPacketInfoManager()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oldValue == HState.CONNECTED) {
|
||||||
|
synchronized (gEarthExtensions) {
|
||||||
|
gEarthExtensions.forEach(GEarthExtension::connectionEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
228
G-Earth/src/main/java/gearth/ui/GEarthProperties.java
Normal file
228
G-Earth/src/main/java/gearth/ui/GEarthProperties.java
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package gearth.ui;
|
||||||
|
|
||||||
|
import gearth.GEarth;
|
||||||
|
import gearth.misc.BindingsUtil;
|
||||||
|
import gearth.misc.Cacher;
|
||||||
|
import gearth.misc.HostInfo;
|
||||||
|
import gearth.protocol.connection.HClient;
|
||||||
|
import gearth.ui.themes.Theme;
|
||||||
|
import gearth.ui.themes.ThemeFactory;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.binding.ObjectBinding;
|
||||||
|
import javafx.beans.binding.StringBinding;
|
||||||
|
import javafx.beans.property.*;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles G-Earth's observable properties.
|
||||||
|
*
|
||||||
|
* @author Dorving
|
||||||
|
*/
|
||||||
|
public final class GEarthProperties {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(GEarthProperties.class);
|
||||||
|
|
||||||
|
public static final ObjectProperty<Theme> themeProperty = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
|
public static final StringBinding themeTitleBinding;
|
||||||
|
|
||||||
|
public static final ObjectBinding<HostInfo> hostInfoBinding;
|
||||||
|
|
||||||
|
public static final ObjectBinding<Image> logoImageBinding;
|
||||||
|
public static final ObjectBinding<Image> logoSmallImageBinding;
|
||||||
|
public static final ObservableList<Image> icons = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
public static final ObjectBinding<String> styleSheetBinding;
|
||||||
|
public static final ObservableList<String> styleSheets = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
public static final ObjectProperty<HClient> clientTypeProperty = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
|
public static final BooleanProperty autoDetectProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final StringProperty hostProperty = new SimpleStringProperty();
|
||||||
|
public static final IntegerProperty portProperty = new SimpleIntegerProperty();
|
||||||
|
|
||||||
|
public static final BooleanProperty alwaysOnTopProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final BooleanProperty enableDeveloperModeProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final BooleanProperty enableDebugProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final BooleanProperty disablePacketDecryptionProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final BooleanProperty enableSocksProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final StringProperty socksHostProperty = new SimpleStringProperty();
|
||||||
|
public static final IntegerProperty socksPortProperty = new SimpleIntegerProperty();
|
||||||
|
public static final BooleanProperty enableGPythonProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final BooleanProperty alwaysAdminProperty = new SimpleBooleanProperty(false);
|
||||||
|
public static final StringProperty notesProperty = new SimpleStringProperty();
|
||||||
|
|
||||||
|
static {
|
||||||
|
themeProperty.addListener((observable, oldValue, newValue) -> Cacher.put("theme", newValue.title()));
|
||||||
|
final Theme value = Cacher.getCacheContents().has("theme") ?
|
||||||
|
ThemeFactory.themeForTitle(Cacher.getCacheContents().getString("theme")) :
|
||||||
|
ThemeFactory.getDefaultTheme();
|
||||||
|
|
||||||
|
LOGGER.debug("Loading theme {}", value);
|
||||||
|
|
||||||
|
themeProperty.set(Objects.requireNonNull(value, "Unable to load theme"));
|
||||||
|
|
||||||
|
styleSheetBinding = createThemeStylesheetBinding();
|
||||||
|
logoSmallImageBinding = createThemeImageBinding("logoSmall.png");
|
||||||
|
logoImageBinding = createThemeImageBinding("logo.png");
|
||||||
|
hostInfoBinding = createThemeHostInfoBinding();
|
||||||
|
themeTitleBinding = createThemeTitleBinding();
|
||||||
|
|
||||||
|
BindingsUtil.addAndBindContent(icons, logoSmallImageBinding);
|
||||||
|
BindingsUtil.addAndBindContent(styleSheets, styleSheetBinding);
|
||||||
|
|
||||||
|
Cacher.bindEnum("last_client_mode", HClient.class, clientTypeProperty);
|
||||||
|
Cacher.bindBoolean("auto_detect", autoDetectProperty);
|
||||||
|
Cacher.bindString("host", hostProperty);
|
||||||
|
Cacher.bindNumber("port", portProperty);
|
||||||
|
convertOldConnectionSettingsIfPresent();
|
||||||
|
|
||||||
|
Cacher.bindBoolean("always_on_top", alwaysOnTopProperty);
|
||||||
|
Cacher.bindBoolean("always_admin", alwaysAdminProperty);
|
||||||
|
Cacher.bindBoolean("develop_mode", enableDeveloperModeProperty);
|
||||||
|
Cacher.bindBoolean("debug_mode_enabled", enableDebugProperty);
|
||||||
|
Cacher.bindBoolean("packet_decryption_disabled", disablePacketDecryptionProperty);
|
||||||
|
Cacher.bindBoolean("socks_enabled", enableSocksProperty);
|
||||||
|
Cacher.bindString("socks_host", socksHostProperty);
|
||||||
|
Cacher.bindNumber("socks_port", socksPortProperty);
|
||||||
|
Cacher.bindBoolean("use_gpython", enableGPythonProperty);
|
||||||
|
Cacher.bindString("notepad_text", notesProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Theme getTheme() {
|
||||||
|
return themeProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getThemeTitle() {
|
||||||
|
return themeTitleBinding.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HostInfo getHostInfo() {
|
||||||
|
return hostInfoBinding.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image getLogoImage() {
|
||||||
|
return logoImageBinding.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image getLogoSmallImage() {
|
||||||
|
return logoSmallImageBinding.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStyleSheet() {
|
||||||
|
return styleSheetBinding.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HClient getClientType() {
|
||||||
|
return clientTypeProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPacketDecryptionDisabled() {
|
||||||
|
return disablePacketDecryptionProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDebugModeEnabled() {
|
||||||
|
return enableDebugProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDeveloperModeEnabled() {
|
||||||
|
return enableDeveloperModeProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAlwaysOnTop() {
|
||||||
|
return alwaysOnTopProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSocksHost() {
|
||||||
|
return socksHostProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getSocksPort() {
|
||||||
|
return socksPortProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StringBinding createThemeTitleBinding() {
|
||||||
|
return Bindings.createStringBinding(() -> {
|
||||||
|
final Theme theme = getTheme();
|
||||||
|
return theme.overridesTitle() ? theme.title() : ThemeFactory.getDefaultTheme().title();
|
||||||
|
}, themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ObjectBinding<HostInfo> createThemeHostInfoBinding() {
|
||||||
|
return Bindings.createObjectBinding(() -> new HostInfo(
|
||||||
|
"G-Earth",
|
||||||
|
GEarth.version,
|
||||||
|
new HashMap<>(Collections.singletonMap("theme", getTheme().title()))
|
||||||
|
), themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ObjectBinding<String> createThemeStylesheetBinding() {
|
||||||
|
return Bindings.createObjectBinding(() -> {
|
||||||
|
final String pathToStyleSheet = getThemeRelativePath("styling.css");
|
||||||
|
final URL styleSheetInput = GEarth.class.getResource(pathToStyleSheet);
|
||||||
|
if (styleSheetInput == null) {
|
||||||
|
LOGGER.error("Could not load style sheet `{}`, input-stream is null for {}", "styling.css", pathToStyleSheet);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return styleSheetInput.toExternalForm();
|
||||||
|
}, themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ObjectBinding<Image> createThemeImageBinding(String imageName) {
|
||||||
|
return Bindings.createObjectBinding(() -> {
|
||||||
|
final Theme theme = getTheme();
|
||||||
|
final String pathToLogo = getThemeRelativePath(theme.overridesLogo()
|
||||||
|
? theme
|
||||||
|
: ThemeFactory.getDefaultTheme(), imageName);
|
||||||
|
try (final InputStream imageInput = GEarth.class.getResourceAsStream(pathToLogo)) {
|
||||||
|
if (imageInput == null) {
|
||||||
|
LOGGER.error("Could not load image `{}`, input-stream is null for {}", imageName, pathToLogo);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new Image(imageInput);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Failed to load image `{}", imageName, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, themeProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getThemeRelativePath(String fileName) {
|
||||||
|
return getThemeRelativePath(getTheme(), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getThemeRelativePath(Theme theme, String fileName) {
|
||||||
|
return String.format("/gearth/ui/themes/%s/" + fileName, theme.internalName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String KEY_LAST_CONNECTION_SETTINGS = "last_connection_settings";
|
||||||
|
private static final String KEY_AUTODETECT = "auto_detect";
|
||||||
|
private static final String KEY_HOST = "host";
|
||||||
|
private static final String KEY_PORT = "port";
|
||||||
|
|
||||||
|
private static void convertOldConnectionSettingsIfPresent() {
|
||||||
|
/*
|
||||||
|
BACKWARDS COMPATABILITY
|
||||||
|
*/
|
||||||
|
if (Cacher.getCacheContents().has(KEY_LAST_CONNECTION_SETTINGS)) {
|
||||||
|
final JSONObject jsonObject = Cacher.getCacheContents().getJSONObject(KEY_LAST_CONNECTION_SETTINGS);
|
||||||
|
if (jsonObject != null) {
|
||||||
|
autoDetectProperty.set(jsonObject.getBoolean(KEY_AUTODETECT));
|
||||||
|
hostProperty.set(jsonObject.getString(KEY_HOST));
|
||||||
|
portProperty.set(jsonObject.getInt(KEY_PORT));
|
||||||
|
Cacher.getCacheContents().remove(KEY_LAST_CONNECTION_SETTINGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,19 @@
|
|||||||
package gearth.ui.subforms.connection;
|
package gearth.ui.subforms.connection;
|
||||||
|
|
||||||
import gearth.GEarth;
|
import gearth.GEarth;
|
||||||
import gearth.misc.Cacher;
|
import gearth.misc.BindingsUtil;
|
||||||
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.connection.HClient;
|
import gearth.protocol.connection.HClient;
|
||||||
import gearth.protocol.connection.HState;
|
import gearth.protocol.connection.HState;
|
||||||
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
||||||
import gearth.services.Constants;
|
import gearth.services.Constants;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.translations.TranslatableString;
|
import gearth.ui.translations.TranslatableString;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.ui.SubForm;
|
import gearth.ui.SubForm;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -22,11 +22,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class ConnectionController extends SubForm {
|
public class ConnectionController extends SubForm {
|
||||||
|
|
||||||
private final String CONNECTION_INFO_CACHE_KEY = "last_connection_settings";
|
|
||||||
private final String AUTODETECT_CACHE = "auto_detect";
|
|
||||||
private final String HOST_CACHE = "host";
|
|
||||||
private final String PORT_CACHE = "port";
|
|
||||||
|
|
||||||
public ComboBox<String> inpPort;
|
public ComboBox<String> inpPort;
|
||||||
public ComboBox<String> inpHost;
|
public ComboBox<String> inpHost;
|
||||||
public Button btnConnect;
|
public Button btnConnect;
|
||||||
@ -40,7 +35,6 @@ public class ConnectionController extends SubForm {
|
|||||||
private volatile int fullyInitialized = 0;
|
private volatile int fullyInitialized = 0;
|
||||||
|
|
||||||
|
|
||||||
public static final String CLIENT_CACHE_KEY = "last_client_mode";
|
|
||||||
public ToggleGroup tgl_clientMode;
|
public ToggleGroup tgl_clientMode;
|
||||||
public RadioButton rd_unity;
|
public RadioButton rd_unity;
|
||||||
public RadioButton rd_flash;
|
public RadioButton rd_flash;
|
||||||
@ -59,38 +53,16 @@ public class ConnectionController extends SubForm {
|
|||||||
Constants.UNITY_PACKETS = rd_unity.isSelected();
|
Constants.UNITY_PACKETS = rd_unity.isSelected();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Cacher.getCacheContents().has(CLIENT_CACHE_KEY)) {
|
GEarthProperties.clientTypeProperty
|
||||||
switch (Cacher.getCacheContents().getEnum(HClient.class, CLIENT_CACHE_KEY)) {
|
.addListener((observable, oldValue, newValue) -> selectClientType(newValue));
|
||||||
case FLASH:
|
selectClientType(GEarthProperties.clientTypeProperty.getValue());
|
||||||
rd_flash.setSelected(true);
|
|
||||||
break;
|
|
||||||
case UNITY:
|
|
||||||
rd_unity.setSelected(true);
|
|
||||||
break;
|
|
||||||
case NITRO:
|
|
||||||
rd_nitro.setSelected(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
cbx_autodetect.selectedProperty().addListener(observable -> updateInputUI());
|
||||||
|
inpPort.getEditor().textProperty().addListener(observable -> updateInputUI());
|
||||||
|
|
||||||
Object object;
|
BindingsUtil.setAndBindBiDirectional(cbx_autodetect.selectedProperty(), GEarthProperties.autoDetectProperty);
|
||||||
String hostRemember = null;
|
BindingsUtil.setAndBindBiDirectional(outHost.textProperty(), GEarthProperties.hostProperty);
|
||||||
String portRemember = null;
|
BindingsUtil.setAndBindBiDirectional(outPort.textProperty(), GEarthProperties.portProperty);
|
||||||
if ((object = Cacher.get(CONNECTION_INFO_CACHE_KEY)) != null) {
|
|
||||||
JSONObject connectionSettings = (JSONObject) object;
|
|
||||||
boolean autoDetect = connectionSettings.getBoolean(AUTODETECT_CACHE);
|
|
||||||
hostRemember = connectionSettings.getString(HOST_CACHE);
|
|
||||||
portRemember = connectionSettings.getInt(PORT_CACHE) + "";
|
|
||||||
cbx_autodetect.setSelected(autoDetect);
|
|
||||||
}
|
|
||||||
|
|
||||||
inpPort.getEditor().textProperty().addListener(observable -> {
|
|
||||||
updateInputUI();
|
|
||||||
});
|
|
||||||
cbx_autodetect.selectedProperty().addListener(observable -> {
|
|
||||||
updateInputUI();
|
|
||||||
});
|
|
||||||
|
|
||||||
List<String> knownHosts = ProxyProviderFactory.autoDetectHosts;
|
List<String> knownHosts = ProxyProviderFactory.autoDetectHosts;
|
||||||
Set<String> hosts = new HashSet<>();
|
Set<String> hosts = new HashSet<>();
|
||||||
@ -110,6 +82,8 @@ public class ConnectionController extends SubForm {
|
|||||||
|
|
||||||
int hostSelectIndex = 0;
|
int hostSelectIndex = 0;
|
||||||
int portSelectIndex = 0;
|
int portSelectIndex = 0;
|
||||||
|
final String hostRemember = GEarthProperties.hostProperty.get();
|
||||||
|
final String portRemember = Integer.toString(GEarthProperties.portProperty.get());
|
||||||
if (hostRemember != null) {
|
if (hostRemember != null) {
|
||||||
hostSelectIndex = hostsSorted.indexOf(hostRemember);
|
hostSelectIndex = hostsSorted.indexOf(hostRemember);
|
||||||
portSelectIndex = portsSorted.indexOf(portRemember);
|
portSelectIndex = portsSorted.indexOf(portRemember);
|
||||||
@ -138,15 +112,31 @@ public class ConnectionController extends SubForm {
|
|||||||
initLanguageBinding();
|
initLanguageBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void selectClientType(HClient newValue) {
|
||||||
|
switch (newValue) {
|
||||||
|
case FLASH:
|
||||||
|
rd_flash.setSelected(true);
|
||||||
|
break;
|
||||||
|
case UNITY:
|
||||||
|
rd_unity.setSelected(true);
|
||||||
|
break;
|
||||||
|
case NITRO:
|
||||||
|
rd_nitro.setSelected(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void updateInputUI() {
|
private void updateInputUI() {
|
||||||
if (parentController == null) return;
|
if (parentController == null) return;
|
||||||
|
|
||||||
grd_clientSelection.setDisable(getHConnection().getState() != HState.NOT_CONNECTED);
|
final HConnection hConnection = getHConnection();
|
||||||
txtfield_hotelversion.setText(getHConnection().getHotelVersion());
|
final HState hConnectionState = hConnection.getState();
|
||||||
|
|
||||||
btnConnect.setDisable(getHConnection().getState() == HState.PREPARING || getHConnection().getState() == HState.ABORTING);
|
grd_clientSelection.setDisable(hConnectionState != HState.NOT_CONNECTED);
|
||||||
|
txtfield_hotelversion.setText(hConnection.getHotelVersion());
|
||||||
|
|
||||||
|
btnConnect.setDisable(hConnectionState == HState.PREPARING || hConnectionState == HState.ABORTING);
|
||||||
|
|
||||||
|
|
||||||
if (!cbx_autodetect.isSelected() && !btnConnect.isDisable() && useFlash()) {
|
if (!cbx_autodetect.isSelected() && !btnConnect.isDisable() && useFlash()) {
|
||||||
@ -159,15 +149,15 @@ public class ConnectionController extends SubForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inpHost.setDisable(getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
inpHost.setDisable(hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||||
inpPort.setDisable(getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
inpPort.setDisable(hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||||
|
|
||||||
cbx_autodetect.setDisable(!useFlash());
|
cbx_autodetect.setDisable(!useFlash());
|
||||||
outHost.setDisable(!useFlash());
|
outHost.setDisable(!useFlash());
|
||||||
outPort.setDisable(!useFlash());
|
outPort.setDisable(!useFlash());
|
||||||
|
|
||||||
inpHost.setDisable(!useFlash() || getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
inpHost.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||||
inpPort.setDisable(!useFlash() || getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
inpPort.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onParentSet(){
|
public void onParentSet(){
|
||||||
@ -178,37 +168,28 @@ public class ConnectionController extends SubForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(() -> {
|
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> Platform.runLater(() -> {
|
||||||
updateInputUI();
|
updateInputUI();
|
||||||
if (newState == HState.NOT_CONNECTED) {
|
if (newValue == HState.NOT_CONNECTED) {
|
||||||
state.setKey(0, "tab.connection.state.notconnected");
|
state.setKey(0, "tab.connection.state.notconnected");
|
||||||
connect.setKey(0, "tab.connection.button.connect");
|
connect.setKey(0, "tab.connection.button.connect");
|
||||||
outHost.setText("");
|
outHost.setText("");
|
||||||
outPort.setText("");
|
outPort.setText("");
|
||||||
}
|
}
|
||||||
else if (oldState == HState.NOT_CONNECTED) {
|
else if (oldValue == HState.NOT_CONNECTED)
|
||||||
connect.setKey(0, "tab.connection.button.abort");
|
connect.setKey(0, "tab.connection.button.abort");
|
||||||
}
|
if (newValue == HState.CONNECTED)
|
||||||
|
|
||||||
if (newState == HState.CONNECTED) {
|
|
||||||
state.setKey(0, "tab.connection.state.connected");
|
state.setKey(0, "tab.connection.state.connected");
|
||||||
}
|
if (newValue == HState.WAITING_FOR_CLIENT)
|
||||||
if (newState == HState.WAITING_FOR_CLIENT) {
|
|
||||||
state.setKey(0, "tab.connection.state.waiting");
|
state.setKey(0, "tab.connection.state.waiting");
|
||||||
|
if (newValue == HState.CONNECTED && useFlash()) {
|
||||||
|
final String host = getHConnection().getDomain();
|
||||||
|
final int port = getHConnection().getServerPort();
|
||||||
|
outHost.setText(host);
|
||||||
|
outPort.setText(Integer.toString(port));
|
||||||
|
GEarthProperties.hostProperty.set(host);
|
||||||
|
GEarthProperties.portProperty.set(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newState == HState.CONNECTED && useFlash()) {
|
|
||||||
outHost.setText(getHConnection().getDomain());
|
|
||||||
outPort.setText(getHConnection().getServerPort()+"");
|
|
||||||
|
|
||||||
JSONObject connectionSettings = new JSONObject();
|
|
||||||
connectionSettings.put(AUTODETECT_CACHE, cbx_autodetect.isSelected());
|
|
||||||
connectionSettings.put(HOST_CACHE, inpHost.getEditor().getText());
|
|
||||||
connectionSettings.put(PORT_CACHE, Integer.parseInt(inpPort.getEditor().getText()));
|
|
||||||
|
|
||||||
Cacher.put(CONNECTION_INFO_CACHE_KEY, connectionSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Platform.runLater(this::updateInputUI);
|
Platform.runLater(this::updateInputUI);
|
||||||
@ -234,9 +215,11 @@ public class ConnectionController extends SubForm {
|
|||||||
String port = GEarth.getArgument("--port");
|
String port = GEarth.getArgument("--port");
|
||||||
if (host != null && port != null) {
|
if (host != null && port != null) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
if (!inpHost.getItems().contains(host)) inpHost.getItems().add(host);
|
if (!inpHost.getItems().contains(host))
|
||||||
|
inpHost.getItems().add(host);
|
||||||
inpHost.getSelectionModel().select(host);
|
inpHost.getSelectionModel().select(host);
|
||||||
if (!inpPort.getItems().contains(port)) inpPort.getItems().add(port);
|
if (!inpPort.getItems().contains(port))
|
||||||
|
inpPort.getItems().add(port);
|
||||||
inpPort.getSelectionModel().select(port);
|
inpPort.getSelectionModel().select(port);
|
||||||
cbx_autodetect.setSelected(false);
|
cbx_autodetect.setSelected(false);
|
||||||
});
|
});
|
||||||
@ -275,12 +258,9 @@ public class ConnectionController extends SubForm {
|
|||||||
} else if (isClientMode(HClient.NITRO)) {
|
} else if (isClientMode(HClient.NITRO)) {
|
||||||
getHConnection().startNitro();
|
getHConnection().startNitro();
|
||||||
}
|
}
|
||||||
|
if (GEarthProperties.isDebugModeEnabled())
|
||||||
|
System.out.println("connecting");
|
||||||
if (HConnection.DEBUG) System.out.println("connecting");
|
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getHConnection().abort();
|
getHConnection().abort();
|
||||||
@ -289,13 +269,10 @@ public class ConnectionController extends SubForm {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onExit() {
|
protected void onExit() {
|
||||||
if (rd_flash.isSelected()) {
|
GEarthProperties.clientTypeProperty.set(
|
||||||
Cacher.put(CLIENT_CACHE_KEY, HClient.FLASH);
|
rd_flash.isSelected() ? HClient.FLASH
|
||||||
} else if (rd_unity.isSelected()) {
|
: rd_unity.isSelected() ? HClient.UNITY
|
||||||
Cacher.put(CLIENT_CACHE_KEY, HClient.UNITY);
|
: HClient.NITRO);
|
||||||
} else if (rd_nitro.isSelected()) {
|
|
||||||
Cacher.put(CLIENT_CACHE_KEY, HClient.NITRO);
|
|
||||||
}
|
|
||||||
getHConnection().abort();
|
getHConnection().abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import gearth.services.extension_handler.extensions.implementations.network.exec
|
|||||||
import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunner;
|
import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunner;
|
||||||
import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunnerFactory;
|
import gearth.services.extension_handler.extensions.implementations.network.executer.ExtensionRunnerFactory;
|
||||||
import gearth.services.g_python.GPythonShell;
|
import gearth.services.g_python.GPythonShell;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.SubForm;
|
import gearth.ui.SubForm;
|
||||||
import gearth.ui.subforms.extensions.logger.ExtensionLogger;
|
import gearth.ui.subforms.extensions.logger.ExtensionLogger;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
@ -48,6 +49,8 @@ public class ExtensionsController extends SubForm {
|
|||||||
scroller.widthProperty().addListener(observable -> header_ext.setPrefWidth(scroller.getWidth()));
|
scroller.widthProperty().addListener(observable -> header_ext.setPrefWidth(scroller.getWidth()));
|
||||||
extensionLogger = new ExtensionLogger();
|
extensionLogger = new ExtensionLogger();
|
||||||
|
|
||||||
|
btn_install.disableProperty().bind(GEarthProperties.enableDeveloperModeProperty.not());
|
||||||
|
|
||||||
initLanguageBinding();
|
initLanguageBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,8 +82,6 @@ public class ExtensionsController extends SubForm {
|
|||||||
extensionLogger.log(text);
|
extensionLogger.log(text);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
getHConnection().onDeveloperModeChange(this::setLocalInstallingEnabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
package gearth.ui.subforms.extra;
|
package gearth.ui.subforms.extra;
|
||||||
|
|
||||||
import gearth.GEarth;
|
import gearth.GEarth;
|
||||||
import gearth.misc.Cacher;
|
import gearth.misc.BindingsUtil;
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.protocol.connection.HState;
|
import gearth.protocol.connection.HState;
|
||||||
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
||||||
import gearth.protocol.connection.proxy.SocksConfiguration;
|
import gearth.protocol.connection.proxy.SocksConfiguration;
|
||||||
import gearth.services.always_admin.AdminService;
|
import gearth.services.always_admin.AdminService;
|
||||||
import gearth.services.g_python.GPythonVersionUtils;
|
import gearth.services.g_python.GPythonVersionUtils;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.SubForm;
|
import gearth.ui.SubForm;
|
||||||
import gearth.ui.subforms.info.InfoController;
|
import gearth.ui.subforms.info.InfoController;
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import gearth.ui.translations.TranslatableString;
|
import gearth.ui.translations.TranslatableString;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.FlowPane;
|
import javafx.scene.layout.FlowPane;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -31,16 +31,6 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
|||||||
|
|
||||||
public static final String INFO_URL_GPYTHON = "https://github.com/sirjonasxx/G-Earth/wiki/G-Python-qtConsole";
|
public static final String INFO_URL_GPYTHON = "https://github.com/sirjonasxx/G-Earth/wiki/G-Python-qtConsole";
|
||||||
|
|
||||||
public static final String NOTEPAD_CACHE_KEY = "notepad_text";
|
|
||||||
public static final String DEVELOP_CACHE_KEY = "develop_mode";
|
|
||||||
public static final String ALWAYS_ADMIN_KEY = "always_admin";
|
|
||||||
public static final String SOCKS_CACHE_KEY = "socks_config";
|
|
||||||
public static final String GPYTHON_CACHE_KEY = "use_gpython";
|
|
||||||
|
|
||||||
public static final String SOCKS_IP = "ip";
|
|
||||||
public static final String SOCKS_PORT = "port";
|
|
||||||
// public static final String IGNORE_ONCE = "ignore_once";
|
|
||||||
|
|
||||||
|
|
||||||
public TextArea txtarea_notepad;
|
public TextArea txtarea_notepad;
|
||||||
|
|
||||||
@ -69,32 +59,23 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
|||||||
url_troubleshooting.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting"));
|
url_troubleshooting.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting"));
|
||||||
InfoController.activateHyperlink(url_troubleshooting);
|
InfoController.activateHyperlink(url_troubleshooting);
|
||||||
|
|
||||||
String notepadInitValue = (String)Cacher.get(NOTEPAD_CACHE_KEY);
|
BindingsUtil.setAndBindBiDirectional(txtarea_notepad.textProperty(), GEarthProperties.notesProperty);
|
||||||
if (notepadInitValue != null) {
|
|
||||||
txtarea_notepad.setText(notepadInitValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cacher.getCacheContents().has(SOCKS_CACHE_KEY)) {
|
txt_socksIp.textProperty().set(GEarthProperties.getSocksHost()+":"+GEarthProperties.getSocksPort());
|
||||||
JSONObject socksInitValue = Cacher.getCacheContents().getJSONObject(SOCKS_CACHE_KEY);
|
GEarthProperties.socksHostProperty.bind(Bindings.createStringBinding(this::getSocksHost, txt_socksIp.textProperty()));
|
||||||
txt_socksIp.setText(socksInitValue.getString(SOCKS_IP) + ":" + socksInitValue.getInt(SOCKS_PORT));
|
GEarthProperties.socksPortProperty.bind(Bindings.createIntegerBinding(this::getSocksPort, txt_socksIp.textProperty()));
|
||||||
// cbx_socksUseIfNeeded.setSelected(socksInitValue.getBoolean(IGNORE_ONCE));
|
grd_socksInfo.disableProperty().bind(GEarthProperties.enableSocksProperty.not());
|
||||||
}
|
|
||||||
|
|
||||||
if (Cacher.getCacheContents().has(GPYTHON_CACHE_KEY)) {
|
|
||||||
cbx_gpython.setSelected(Cacher.getCacheContents().getBoolean(GPYTHON_CACHE_KEY));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cacher.getCacheContents().has(ALWAYS_ADMIN_KEY)) {
|
|
||||||
cbx_admin.setSelected(Cacher.getCacheContents().getBoolean(ALWAYS_ADMIN_KEY));
|
|
||||||
}
|
|
||||||
|
|
||||||
cbx_debug.selectedProperty().addListener(observable -> HConnection.DEBUG = cbx_debug.isSelected());
|
|
||||||
cbx_disableDecryption.selectedProperty().addListener(observable -> HConnection.DECRYPTPACKETS = !cbx_disableDecryption.isSelected());
|
|
||||||
|
|
||||||
cbx_useSocks.selectedProperty().addListener(observable -> grd_socksInfo.setDisable(!cbx_useSocks.isSelected()));
|
|
||||||
|
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_useSocks.selectedProperty(), GEarthProperties.enableSocksProperty);
|
||||||
ProxyProviderFactory.setSocksConfig(this);
|
ProxyProviderFactory.setSocksConfig(this);
|
||||||
|
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_debug.selectedProperty(), GEarthProperties.enableDebugProperty);
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_disableDecryption.selectedProperty(), GEarthProperties.disablePacketDecryptionProperty);
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_alwaysOnTop.selectedProperty(), GEarthProperties.alwaysOnTopProperty);
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_develop.selectedProperty(), GEarthProperties.enableDeveloperModeProperty);
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_admin.selectedProperty(), GEarthProperties.alwaysAdminProperty);
|
||||||
|
BindingsUtil.setAndBindBiDirectional(cbx_gpython.selectedProperty(), GEarthProperties.enableGPythonProperty);
|
||||||
|
|
||||||
initLanguageBinding();
|
initLanguageBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,47 +83,16 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
|||||||
protected void onParentSet() {
|
protected void onParentSet() {
|
||||||
adminService = new AdminService(cbx_admin.isSelected(), getHConnection());
|
adminService = new AdminService(cbx_admin.isSelected(), getHConnection());
|
||||||
getHConnection().addTrafficListener(1, message -> adminService.onMessage(message));
|
getHConnection().addTrafficListener(1, message -> adminService.onMessage(message));
|
||||||
getHConnection().getStateObservable().addListener((oldState, newState) -> {if (newState == HState.CONNECTED) adminService.onConnect();});
|
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
if (newValue == HState.CONNECTED)
|
||||||
parentController.getStage().setAlwaysOnTop(cbx_alwaysOnTop.isSelected());
|
adminService.onConnect();
|
||||||
cbx_alwaysOnTop.selectedProperty().addListener(observable -> parentController.getStage().setAlwaysOnTop(cbx_alwaysOnTop.isSelected()));
|
if (oldValue == HState.NOT_CONNECTED || newValue == HState.NOT_CONNECTED)
|
||||||
|
|
||||||
cbx_advanced.selectedProperty().addListener(observable -> updateAdvancedUI());
|
|
||||||
getHConnection().getStateObservable().addListener((oldState, newState) -> {
|
|
||||||
if (oldState == HState.NOT_CONNECTED || newState == HState.NOT_CONNECTED) {
|
|
||||||
updateAdvancedUI();
|
updateAdvancedUI();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
cbx_advanced.selectedProperty().addListener(observable -> updateAdvancedUI());
|
||||||
if (Cacher.getCacheContents().has(DEVELOP_CACHE_KEY)) {
|
|
||||||
boolean inDevelopMode = Cacher.getCacheContents().getBoolean(DEVELOP_CACHE_KEY);
|
|
||||||
setDevelopMode(inDevelopMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateAdvancedUI();
|
updateAdvancedUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onExit() {
|
|
||||||
Cacher.put(NOTEPAD_CACHE_KEY, txtarea_notepad.getText());
|
|
||||||
Cacher.put(GPYTHON_CACHE_KEY, cbx_gpython.isSelected());
|
|
||||||
Cacher.put(ALWAYS_ADMIN_KEY, cbx_admin.isSelected());
|
|
||||||
Cacher.put(DEVELOP_CACHE_KEY, cbx_develop.isSelected());
|
|
||||||
saveSocksConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveSocksConfig() {
|
|
||||||
if (txt_socksIp.getText().contains(":")) {
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
jsonObject.put(SOCKS_IP, getSocksHost());
|
|
||||||
jsonObject.put(SOCKS_PORT, getSocksPort());
|
|
||||||
Cacher.put(SOCKS_CACHE_KEY, jsonObject);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Cacher.remove(SOCKS_CACHE_KEY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateAdvancedUI() {
|
private void updateAdvancedUI() {
|
||||||
if (!cbx_advanced.isSelected()) {
|
if (!cbx_advanced.isSelected()) {
|
||||||
cbx_debug.setSelected(false);
|
cbx_debug.setSelected(false);
|
||||||
@ -158,7 +108,6 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useSocks() {
|
public boolean useSocks() {
|
||||||
saveSocksConfig();
|
|
||||||
return cbx_useSocks.isSelected();
|
return cbx_useSocks.isSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +214,6 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
|||||||
|
|
||||||
private void setDevelopMode(boolean enabled) {
|
private void setDevelopMode(boolean enabled) {
|
||||||
cbx_develop.setSelected(enabled);
|
cbx_develop.setSelected(enabled);
|
||||||
getHConnection().setDeveloperMode(enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void adminCbxClick(ActionEvent actionEvent) {
|
public void adminCbxClick(ActionEvent actionEvent) {
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
package gearth.ui.subforms.info;
|
package gearth.ui.subforms.info;
|
||||||
|
|
||||||
import gearth.GEarth;
|
import gearth.GEarth;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import gearth.ui.translations.TranslatableString;
|
import gearth.ui.translations.TranslatableString;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import gearth.ui.SubForm;
|
import gearth.ui.SubForm;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.web.WebView;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 06/04/18.
|
* Created by Jonas on 06/04/18.
|
||||||
*/
|
*/
|
||||||
public class InfoController extends SubForm {
|
public class InfoController extends SubForm implements Initializable {
|
||||||
public ImageView img_logo;
|
public ImageView img_logo;
|
||||||
public Hyperlink link_darkbox;
|
public Hyperlink link_darkbox;
|
||||||
public Hyperlink link_g_gearth;
|
public Hyperlink link_g_gearth;
|
||||||
@ -38,7 +41,12 @@ public class InfoController extends SubForm {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
@Override
|
||||||
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
|
||||||
|
img_logo.imageProperty().bind(GEarthProperties.logoImageBinding);
|
||||||
|
version.textProperty().bind(GEarthProperties.themeTitleBinding);
|
||||||
|
|
||||||
link_darkbox.setTooltip(new Tooltip("https://darkbox.nl"));
|
link_darkbox.setTooltip(new Tooltip("https://darkbox.nl"));
|
||||||
link_d_gearth.setTooltip(new Tooltip("https://discord.gg/AVkcF8y"));
|
link_d_gearth.setTooltip(new Tooltip("https://discord.gg/AVkcF8y"));
|
||||||
link_g_gearth.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth"));
|
link_g_gearth.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth"));
|
||||||
@ -87,4 +95,5 @@ public class InfoController extends SubForm {
|
|||||||
|
|
||||||
btn_donate.textProperty().bind(new TranslatableString("%s", "tab.info.donate"));
|
btn_donate.textProperty().bind(new TranslatableString("%s", "tab.info.donate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,14 @@ import gearth.misc.Cacher;
|
|||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.HMessage;
|
import gearth.protocol.HMessage;
|
||||||
import gearth.protocol.HPacket;
|
import gearth.protocol.HPacket;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.SubForm;
|
import gearth.ui.SubForm;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import gearth.ui.translations.TranslatableString;
|
import gearth.ui.translations.TranslatableString;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.InvalidationListener;
|
||||||
|
import javafx.beans.Observable;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
@ -38,10 +42,10 @@ public class InjectionController extends SubForm {
|
|||||||
private TranslatableString corruption, pcktInfo;
|
private TranslatableString corruption, pcktInfo;
|
||||||
|
|
||||||
protected void onParentSet() {
|
protected void onParentSet() {
|
||||||
getHConnection().onDeveloperModeChange(developMode -> updateUI());
|
final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI);
|
||||||
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(this::updateUI));
|
GEarthProperties.enableDeveloperModeProperty.addListener(updateUI);
|
||||||
|
getHConnection().stateProperty().addListener(updateUI);
|
||||||
inputPacket.textProperty().addListener(event -> Platform.runLater(this::updateUI));
|
inputPacket.textProperty().addListener(updateUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
@ -9,6 +9,15 @@ import gearth.services.scheduler.listeners.OnBeingUpdatedListener;
|
|||||||
import gearth.services.scheduler.listeners.OnDeleteListener;
|
import gearth.services.scheduler.listeners.OnDeleteListener;
|
||||||
import gearth.services.scheduler.listeners.OnEditListener;
|
import gearth.services.scheduler.listeners.OnEditListener;
|
||||||
import gearth.services.scheduler.listeners.OnUpdatedListener;
|
import gearth.services.scheduler.listeners.OnUpdatedListener;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.ObjectPropertyBase;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.Event;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.event.EventType;
|
||||||
|
import javafx.scene.control.ButtonBase;
|
||||||
|
import javafx.scene.control.TreeItem;
|
||||||
|
import javafx.scene.control.TreeView;
|
||||||
|
|
||||||
public class InteractableScheduleItem extends ScheduleItem implements StringifyAble {
|
public class InteractableScheduleItem extends ScheduleItem implements StringifyAble {
|
||||||
|
|
||||||
|
@ -7,9 +7,12 @@ import gearth.protocol.StateChangeListener;
|
|||||||
import gearth.protocol.connection.HState;
|
import gearth.protocol.connection.HState;
|
||||||
import gearth.services.scheduler.Interval;
|
import gearth.services.scheduler.Interval;
|
||||||
import gearth.services.scheduler.Scheduler;
|
import gearth.services.scheduler.Scheduler;
|
||||||
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import gearth.ui.translations.TranslatableString;
|
import gearth.ui.translations.TranslatableString;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.InvalidationListener;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
@ -88,8 +91,9 @@ public class SchedulerController extends SubForm {
|
|||||||
@Override
|
@Override
|
||||||
protected void onParentSet() {
|
protected void onParentSet() {
|
||||||
scheduler = new Scheduler<>(getHConnection());
|
scheduler = new Scheduler<>(getHConnection());
|
||||||
getHConnection().onDeveloperModeChange(developMode -> updateUI());
|
final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI);
|
||||||
getHConnection().getStateObservable().addListener((oldState, newState) -> updateUI());
|
GEarthProperties.enableDeveloperModeProperty.addListener(updateUI);
|
||||||
|
getHConnection().stateProperty().addListener(updateUI);
|
||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
package gearth.ui.titlebar;
|
package gearth.ui.titlebar;
|
||||||
|
|
||||||
import gearth.GEarth;
|
import gearth.ui.GEarthProperties;
|
||||||
import gearth.ui.themes.Theme;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class GEarthThemedTitleBarConfig extends DefaultTitleBarConfig {
|
public class GEarthThemedTitleBarConfig extends DefaultTitleBarConfig {
|
||||||
|
|
||||||
public GEarthThemedTitleBarConfig(Stage stage) {
|
public GEarthThemedTitleBarConfig(Stage stage) {
|
||||||
super(stage, GEarth.getTheme());
|
super(stage, GEarthProperties.getTheme());
|
||||||
GEarth.getThemeObservable().addListener(this::setTheme);
|
GEarthProperties.themeProperty.addListener((observable, oldValue, newValue) -> setTheme(newValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user