mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-26 18:30:52 +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>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dustinredmond.fxtrayicon</groupId>
|
||||
<artifactId>FXTrayIcon</artifactId>
|
||||
<version>4.0.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
|
@ -1,41 +1,33 @@
|
||||
package gearth;
|
||||
|
||||
import gearth.misc.AdminValidator;
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.misc.UpdateChecker;
|
||||
import gearth.misc.listenerpattern.ObservableObject;
|
||||
import gearth.ui.GEarthController;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.themes.Theme;
|
||||
import gearth.ui.themes.ThemeFactory;
|
||||
import gearth.ui.titlebar.TitleBarConfig;
|
||||
import gearth.ui.titlebar.TitleBarController;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GEarth extends Application {
|
||||
|
||||
public static GEarth main;
|
||||
public static String version = "1.5.3";
|
||||
public static String gitApi = "https://api.github.com/repos/sirjonasxx/G-Earth/releases/latest";
|
||||
public static ObservableObject<Theme> observableTheme;
|
||||
|
||||
private Stage stage;
|
||||
private GEarthController controller;
|
||||
|
||||
static {
|
||||
observableTheme = new ObservableObject<>(
|
||||
Cacher.getCacheContents().has("theme") ?
|
||||
ThemeFactory.themeForTitle(Cacher.getCacheContents().getString("theme")) :
|
||||
ThemeFactory.getDefaultTheme()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
@ -52,9 +44,28 @@ public class GEarth extends Application {
|
||||
}
|
||||
controller = loader.getController();
|
||||
controller.setStage(primaryStage);
|
||||
stage.initStyle(StageStyle.TRANSPARENT);
|
||||
|
||||
primaryStage.initStyle(StageStyle.TRANSPARENT);
|
||||
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() {
|
||||
@Override
|
||||
public boolean displayThemePicker() {
|
||||
@ -66,11 +77,6 @@ public class GEarth extends Application {
|
||||
return true;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean allowResizing() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onCloseClicked() {
|
||||
closeGEarth();
|
||||
@ -83,25 +89,20 @@ public class GEarth extends Application {
|
||||
|
||||
@Override
|
||||
public void setTheme(Theme theme) {
|
||||
setGearthTheme(theme);
|
||||
GEarthProperties.themeProperty.set(theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
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() {
|
||||
@ -110,30 +111,6 @@ public class GEarth extends Application {
|
||||
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 void main(String[] args) {
|
||||
@ -161,14 +138,6 @@ public class GEarth extends Application {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ObservableObject<Theme> getThemeObservable() {
|
||||
return observableTheme;
|
||||
}
|
||||
|
||||
public static Theme getTheme() {
|
||||
return observableTheme.getObject();
|
||||
}
|
||||
|
||||
public static void setAlertOwner(Alert alert) {
|
||||
alert.initOwner(main.stage);
|
||||
}
|
||||
|
@ -2,19 +2,14 @@ package gearth.extensions;
|
||||
|
||||
import gearth.misc.HostInfo;
|
||||
import gearth.misc.listenerpattern.Observable;
|
||||
import gearth.misc.listenerpattern.ObservableObject;
|
||||
import gearth.protocol.HMessage;
|
||||
import gearth.protocol.HPacket;
|
||||
import gearth.services.packet_info.PacketInfo;
|
||||
import gearth.services.packet_info.PacketInfoManager;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import org.reactfx.util.Lists;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
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 {
|
||||
|
||||
@ -33,10 +28,11 @@ public abstract class ExtensionBase extends IExtension {
|
||||
|
||||
|
||||
volatile PacketInfoManager packetInfoManager = PacketInfoManager.EMPTY;
|
||||
ObservableObject<HostInfo> observableHostInfo = new ObservableObject<>(null);
|
||||
|
||||
ObjectProperty<HostInfo> hostInfoProperty = new SimpleObjectProperty<>();
|
||||
|
||||
void updateHostInfo(HostInfo hostInfo) {
|
||||
observableHostInfo.setObject(hostInfo);
|
||||
hostInfoProperty.set(hostInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +63,7 @@ public abstract class ExtensionBase extends IExtension {
|
||||
* @param messageListener the callback
|
||||
*/
|
||||
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 ?
|
||||
hashOrNameIncomingListeners :
|
||||
hashOrNameOutgoingListeners;
|
||||
@ -197,6 +193,6 @@ public abstract class ExtensionBase extends IExtension {
|
||||
}
|
||||
|
||||
public HostInfo getHostInfo() {
|
||||
return observableHostInfo.getObject();
|
||||
return hostInfoProperty.get();
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package gearth.extensions;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.operations.Bool;
|
||||
import gearth.misc.HostInfo;
|
||||
import gearth.misc.listenerpattern.Observable;
|
||||
import gearth.services.packet_info.PacketInfoManager;
|
||||
import javafx.application.HostServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.stage.Stage;
|
||||
import gearth.protocol.HMessage;
|
||||
import gearth.protocol.HPacket;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 22/09/18.
|
||||
*/
|
||||
@ -99,8 +99,17 @@ public abstract class ExtensionForm extends ExtensionBase {
|
||||
}
|
||||
|
||||
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.primaryStage = primaryStage;
|
||||
extensionForm.fieldsInitialized.fireEvent();
|
||||
extensionForm.setFieldsInitialised(true);
|
||||
|
||||
Thread t = new Thread(() -> {
|
||||
extension.run();
|
||||
//when the extension has ended, close this process
|
||||
|
@ -55,7 +55,7 @@ public class InternalExtensionFormLauncher<L extends InternalExtensionFormCreato
|
||||
extensionForm.extension = internalExtension;
|
||||
extensionForm.primaryStage = stage;
|
||||
|
||||
extensionForm.fieldsInitialized.fireEvent();
|
||||
extensionForm.setFieldsInitialised(true);
|
||||
GEarthExtension gEarthExtension = new InternalExtensionBuilder(internalExtension);
|
||||
observer.onExtensionProduced(gEarthExtension);
|
||||
|
||||
|
@ -18,8 +18,8 @@ public abstract class ThemedExtensionFormCreator extends ExtensionFormCreator {
|
||||
|
||||
@Override
|
||||
protected ExtensionForm createForm(Stage primaryStage) throws Exception {
|
||||
FXMLLoader loader = new FXMLLoader(getFormResource());
|
||||
Parent root = loader.load();
|
||||
final FXMLLoader loader = new FXMLLoader(getFormResource());
|
||||
final Parent root = loader.load();
|
||||
|
||||
primaryStage.setTitle(getTitle());
|
||||
primaryStage.setScene(new Scene(root));
|
||||
@ -27,31 +27,38 @@ public abstract class ThemedExtensionFormCreator extends ExtensionFormCreator {
|
||||
primaryStage.setResizable(false);
|
||||
primaryStage.sizeToScene();
|
||||
|
||||
Theme defaultTheme = ThemeFactory.getDefaultTheme();
|
||||
DefaultTitleBarConfig config = new DefaultTitleBarConfig(primaryStage, defaultTheme) {
|
||||
final Theme defaultTheme = ThemeFactory.getDefaultTheme();
|
||||
final DefaultTitleBarConfig config = new DefaultTitleBarConfig(primaryStage, defaultTheme) {
|
||||
@Override
|
||||
public boolean displayThemePicker() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
TitleBarController.create(primaryStage, config);
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.getScene().getRoot().getStyleClass().add(defaultTheme.title().replace(" ", "-").toLowerCase());
|
||||
primaryStage.getScene().getRoot().getStyleClass().add(defaultTheme.isDark() ? "g-dark" : "g-light");
|
||||
});
|
||||
Platform.runLater(() -> primaryStage.getScene().getRoot().getStyleClass().addAll(
|
||||
defaultTheme.title().replace(" ", "-").toLowerCase(),
|
||||
defaultTheme.isDark() ? "g-dark" : "g-light"
|
||||
));
|
||||
|
||||
ExtensionForm extensionForm = loader.getController();
|
||||
extensionForm.fieldsInitialized.addListener(() -> extensionForm.extension.observableHostInfo.addListener(hostInfo -> {
|
||||
if (hostInfo.getAttributes().containsKey("theme")) {
|
||||
String themeTitle = hostInfo.getAttributes().get("theme");
|
||||
Theme theme = ThemeFactory.themeForTitle(themeTitle);
|
||||
final ExtensionForm extensionForm = loader.getController();
|
||||
extensionForm
|
||||
.fieldsInitialisedProperty()
|
||||
.addListener(observable -> listenForThemeChange(primaryStage, config, extensionForm));
|
||||
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) {
|
||||
String styleClassOld = config.getCurrentTheme().title().replace(" ", "-").toLowerCase();
|
||||
String lightClassOld = config.getCurrentTheme().isDark() ? "g-dark" : "g-light";
|
||||
String styleClassNew = theme.title().replace(" ", "-").toLowerCase();
|
||||
String lightClassNew = theme.isDark() ? "g-dark" : "g-light";
|
||||
final String styleClassOld = config.getCurrentTheme().title().replace(" ", "-").toLowerCase();
|
||||
final String lightClassOld = config.getCurrentTheme().isDark() ? "g-dark" : "g-light";
|
||||
final String styleClassNew = theme.title().replace(" ", "-").toLowerCase();
|
||||
final String lightClassNew = theme.isDark() ? "g-dark" : "g-light";
|
||||
config.setTheme(theme);
|
||||
Parent currentRoot = primaryStage.getScene().getRoot();
|
||||
final Parent currentRoot = primaryStage.getScene().getRoot();
|
||||
Platform.runLater(() -> {
|
||||
currentRoot.getStyleClass().remove(styleClassOld);
|
||||
currentRoot.getStyleClass().add(styleClassNew);
|
||||
@ -62,13 +69,11 @@ public abstract class ThemedExtensionFormCreator extends ExtensionFormCreator {
|
||||
});
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
return extensionForm;
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract String getTitle();
|
||||
|
||||
protected abstract URL getFormResource();
|
||||
|
||||
// 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;
|
||||
|
||||
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.JSONObject;
|
||||
|
||||
@ -10,6 +14,8 @@ import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 28/09/18.
|
||||
@ -130,4 +136,36 @@ public class Cacher {
|
||||
public static void clear() {
|
||||
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.unity.UnityProxyProvider;
|
||||
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.util.function.Consumer;
|
||||
|
||||
public class HConnection {
|
||||
|
||||
public static volatile boolean DECRYPTPACKETS = true;
|
||||
public static volatile boolean DEBUG = false;
|
||||
|
||||
private volatile ExtensionHandler extensionHandler = null;
|
||||
|
||||
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 ProxyProviderFactory proxyProviderFactory;
|
||||
private ProxyProvider proxyProvider = null;
|
||||
|
||||
private volatile boolean developerMode = false;
|
||||
|
||||
public HConnection() {
|
||||
HConnection selff = this;
|
||||
proxyProviderFactory = new ProxyProviderFactory(
|
||||
@ -47,16 +47,16 @@ public class HConnection {
|
||||
PacketSafetyManager.PACKET_SAFETY_MANAGER.initialize(this);
|
||||
}
|
||||
|
||||
public ObjectProperty<HState> stateProperty() {
|
||||
return stateProperty;
|
||||
}
|
||||
|
||||
public HState getState() {
|
||||
return state;
|
||||
return stateProperty.get();
|
||||
}
|
||||
|
||||
private void setState(HState state) {
|
||||
if (state != this.state) {
|
||||
HState buffer = this.state;
|
||||
this.state = state;
|
||||
stateObservable.fireEvent(l -> l.stateChanged(buffer, state));
|
||||
}
|
||||
stateProperty.set(state);
|
||||
}
|
||||
|
||||
// autodetect mode
|
||||
@ -107,6 +107,7 @@ public class HConnection {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Observable<StateChangeListener> getStateObservable() {
|
||||
return stateObservable;
|
||||
}
|
||||
@ -165,11 +166,12 @@ public class HConnection {
|
||||
}
|
||||
|
||||
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) {
|
||||
if (state != HState.CONNECTED) return false;
|
||||
if (getState() != HState.CONNECTED) return false;
|
||||
|
||||
HProxy proxy = this.proxy;
|
||||
if (proxy == null) return false;
|
||||
@ -196,14 +198,6 @@ public class HConnection {
|
||||
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() {
|
||||
if (proxy == null) {
|
||||
|
@ -10,15 +10,14 @@ import gearth.protocol.memory.Rc4Obtainer;
|
||||
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
|
||||
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
|
||||
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.titlebar.TitleBarController;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
@ -47,7 +46,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
||||
client.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);
|
||||
|
||||
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
|
||||
@ -73,7 +72,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
||||
try {
|
||||
if (!server.isClosed()) server.close();
|
||||
if (!client.isClosed()) client.close();
|
||||
if (HConnection.DEBUG) System.out.println("STOP");
|
||||
if (GEarthProperties.isDebugModeEnabled()) System.out.println("STOP");
|
||||
if (datastream[0]) {
|
||||
onConnectEnd();
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
package gearth.protocol.connection.proxy.flash;
|
||||
|
||||
import gearth.GEarth;
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.connection.*;
|
||||
@ -10,12 +9,11 @@ import gearth.protocol.hostreplacer.hostsfile.HostReplacer;
|
||||
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
|
||||
import gearth.protocol.portchecker.PortChecker;
|
||||
import gearth.protocol.portchecker.PortCheckerFactory;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.titlebar.TitleBarController;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
@ -128,7 +126,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
||||
Socket client = proxy_server.accept();
|
||||
proxy = potentialProxy;
|
||||
closeAllProxies(proxy);
|
||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
||||
if (GEarthProperties.isDebugModeEnabled()) System.out.println("accepted a proxy");
|
||||
|
||||
new Thread(() -> {
|
||||
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.hostreplacer.ipmapping.IpMapper;
|
||||
import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory;
|
||||
import gearth.ui.GEarthProperties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
@ -54,7 +55,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
||||
|
||||
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()));
|
||||
proxy.initProxy(proxy_server);
|
||||
@ -62,10 +63,10 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
||||
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
||||
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||
try {
|
||||
if (HConnection.DEBUG) System.out.println("try accept proxy");
|
||||
if (GEarthProperties.isDebugModeEnabled()) System.out.println("try accept proxy");
|
||||
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(() -> {
|
||||
try {
|
||||
@ -151,7 +152,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
||||
createSocksProxyThread(client);
|
||||
}
|
||||
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 {
|
||||
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.NitroHttpProxyServerCallback;
|
||||
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.LoggerFactory;
|
||||
|
||||
@ -16,7 +18,7 @@ import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
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);
|
||||
|
||||
@ -53,7 +55,7 @@ public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCa
|
||||
originalWebsocketUrl = null;
|
||||
originalCookies = null;
|
||||
|
||||
connection.getStateObservable().addListener(this);
|
||||
connection.stateProperty().addListener(this);
|
||||
|
||||
logger.info("Starting http proxy");
|
||||
|
||||
@ -112,7 +114,7 @@ public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCa
|
||||
|
||||
stateSetter.setState(HState.NOT_CONNECTED);
|
||||
|
||||
connection.getStateObservable().removeListener(this);
|
||||
connection.stateProperty().removeListener(this);
|
||||
|
||||
logger.info("Nitro proxy stopped");
|
||||
}).start();
|
||||
@ -131,16 +133,15 @@ public class NitroProxyProvider implements ProxyProvider, NitroHttpProxyServerCa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(HState oldState, HState newState) {
|
||||
if (oldState == HState.WAITING_FOR_CLIENT && newState == HState.CONNECTED) {
|
||||
public void changed(ObservableValue<? extends HState> observable, HState oldValue, HState newValue) {
|
||||
if (oldValue == HState.WAITING_FOR_CLIENT && newValue == HState.CONNECTED) {
|
||||
// Unregister but do not stop http proxy.
|
||||
// We are not stopping the http proxy because some requests might still require it to be running.
|
||||
nitroHttpProxy.pause();
|
||||
}
|
||||
|
||||
// Catch setState ABORTING inside NitroWebsocketClient.
|
||||
if (newState == HState.ABORTING) {
|
||||
if (newValue == HState.ABORTING)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,21 @@
|
||||
package gearth.protocol.connection.proxy.unity;
|
||||
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.StateChangeListener;
|
||||
import gearth.protocol.connection.HProxySetter;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.HStateSetter;
|
||||
import gearth.protocol.connection.proxy.ProxyProvider;
|
||||
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.Server;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
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.ServerEndpointConfig;
|
||||
@ -22,6 +25,9 @@ import static gearth.services.unity_tools.GUnityFileServer.FILESERVER_PORT;
|
||||
|
||||
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 HStateSetter stateSetter;
|
||||
private final HConnection hConnection;
|
||||
@ -34,7 +40,6 @@ public class UnityProxyProvider implements ProxyProvider {
|
||||
this.hConnection = hConnection;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void start() throws IOException {
|
||||
// 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) {
|
||||
try {
|
||||
packetHandlerServer = new Server(port);
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/ws");
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
final HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[] { context });
|
||||
|
||||
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
||||
final ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
||||
wscontainer.addEndpoint(ServerEndpointConfig.Builder
|
||||
.create(UnityCommunicator.class, "/packethandler") // the endpoint url
|
||||
.configurator(new UnityCommunicatorConfig(proxySetter, stateSetter, hConnection, this))
|
||||
@ -65,10 +70,8 @@ public class UnityProxyProvider implements ProxyProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
if (fail)
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
|
||||
startPortRequestServer(port);
|
||||
startUnityFileServer();
|
||||
@ -79,17 +82,16 @@ public class UnityProxyProvider implements ProxyProvider {
|
||||
try {
|
||||
packetHandlerServer.stop();
|
||||
} 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
|
||||
public synchronized void abort() {
|
||||
if (packetHandlerServer == null) {
|
||||
if (packetHandlerServer == null)
|
||||
return;
|
||||
}
|
||||
|
||||
final Server abortThis = packetHandlerServer;
|
||||
stateSetter.setState(HState.ABORTING);
|
||||
@ -97,7 +99,7 @@ public class UnityProxyProvider implements ProxyProvider {
|
||||
try {
|
||||
abortThis.stop();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.error("Failed to abort", e);
|
||||
} finally {
|
||||
stateSetter.setState(HState.NOT_CONNECTED);
|
||||
}
|
||||
@ -106,43 +108,30 @@ public class UnityProxyProvider implements ProxyProvider {
|
||||
}
|
||||
|
||||
private void startUnityFileServer() throws Exception {
|
||||
Server server = new Server(FILESERVER_PORT);
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
final Server server = new Server(FILESERVER_PORT);
|
||||
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
|
||||
context.addServlet(new ServletHolder(new GUnityFileServer()), "/*");
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
final HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[] { context });
|
||||
server.setHandler(handlers);
|
||||
|
||||
server.start();
|
||||
StateChangeListener fileServerCloser = new StateChangeListener() {
|
||||
@Override
|
||||
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);
|
||||
|
||||
stopServerOnDisconnect(server);
|
||||
}
|
||||
|
||||
private void startPortRequestServer(int packetHandlerPort) throws Exception {
|
||||
Server portRequestServer = new Server(9039);
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
final Server portRequestServer = new Server(PORT_REQUESTER_SERVER_PORT);
|
||||
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/ws");
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
final HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[] { context });
|
||||
portRequestServer.setHandler(handlers);
|
||||
|
||||
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
||||
final ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
|
||||
wscontainer.addEndpoint(ServerEndpointConfig.Builder
|
||||
.create(PortRequester.class, "/portrequest") // the endpoint url
|
||||
.configurator(new PortRequesterConfig(packetHandlerPort))
|
||||
@ -150,19 +139,22 @@ public class UnityProxyProvider implements ProxyProvider {
|
||||
|
||||
portRequestServer.start();
|
||||
|
||||
StateChangeListener portRequesterCloser = new StateChangeListener() {
|
||||
stopServerOnDisconnect(portRequestServer);
|
||||
}
|
||||
|
||||
private void stopServerOnDisconnect(Server server) {
|
||||
hConnection.stateProperty().addListener(new ChangeListener<HState>() {
|
||||
@Override
|
||||
public void stateChanged(HState oldState, HState newState) {
|
||||
if (oldState == HState.WAITING_FOR_CLIENT || newState == HState.NOT_CONNECTED) {
|
||||
hConnection.getStateObservable().removeListener(this);
|
||||
public void changed(ObservableValue<? extends HState> observable, HState oldValue, HState newValue) {
|
||||
if (oldValue == HState.WAITING_FOR_CLIENT || newValue == HState.NOT_CONNECTED) {
|
||||
hConnection.stateProperty().removeListener(this);
|
||||
try {
|
||||
portRequestServer.stop();
|
||||
server.stop();
|
||||
} 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.HabboClientFactory;
|
||||
import gearth.protocol.packethandler.PayloadBuffer;
|
||||
import gearth.protocol.packethandler.flash.BufferChangeListener;
|
||||
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.titlebar.TitleBarController;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
@ -37,21 +39,22 @@ public class Rc4Obtainer {
|
||||
public void setFlashPacketHandlers(FlashPacketHandler... flashPacketHandlers) {
|
||||
this.flashPacketHandlers = Arrays.asList(flashPacketHandlers);
|
||||
for (FlashPacketHandler handler : flashPacketHandlers) {
|
||||
BufferChangeListener bufferChangeListener = new BufferChangeListener() {
|
||||
final InvalidationListener bufferChangeListener = new InvalidationListener() {
|
||||
@Override
|
||||
public void act() {
|
||||
public void invalidated(Observable observable) {
|
||||
if (handler.isEncryptedStream()) {
|
||||
onSendFirstEncryptedMessage(handler);
|
||||
handler.getBufferChangeObservable().removeListener(this);
|
||||
Rc4Obtainer.this.onSendFirstEncryptedMessage(handler);
|
||||
handler.incomingBufferProperty().removeListener(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
handler.getBufferChangeObservable().addListener(bufferChangeListener);
|
||||
handler.incomingBufferProperty().addListener(bufferChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler) {
|
||||
if (!HConnection.DECRYPTPACKETS) return;
|
||||
if (GEarthProperties.isPacketDecryptionDisabled())
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
import gearth.misc.listenerpattern.Observable;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.HMessage;
|
||||
import gearth.protocol.HPacket;
|
||||
import gearth.protocol.crypto.RC4;
|
||||
import gearth.protocol.packethandler.PacketHandler;
|
||||
import gearth.protocol.packethandler.PayloadBuffer;
|
||||
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.OutputStream;
|
||||
@ -18,7 +19,7 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
||||
|
||||
protected static final boolean DEBUG = false;
|
||||
|
||||
private volatile OutputStream out;
|
||||
private final OutputStream out;
|
||||
private volatile boolean isTempBlocked = false;
|
||||
volatile boolean isDataStream = false;
|
||||
|
||||
@ -36,7 +37,7 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
||||
FlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
|
||||
super(extensionHandler, trafficObservables);
|
||||
out = outputStream;
|
||||
this.payloadBuffer = new PayloadBuffer();
|
||||
payloadBuffer = new PayloadBuffer();
|
||||
}
|
||||
|
||||
public boolean isDataStream() {return isDataStream;}
|
||||
@ -49,6 +50,7 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
||||
}
|
||||
|
||||
public void act(byte[] buffer) throws IOException {
|
||||
|
||||
if (!isDataStream) {
|
||||
synchronized (sendLock) {
|
||||
out.write(buffer);
|
||||
@ -56,20 +58,19 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
bufferChangeObservable.fireEvent();
|
||||
incomingBufferProperty.set(buffer);
|
||||
|
||||
if (!isEncryptedStream) {
|
||||
payloadBuffer.push(buffer);
|
||||
}
|
||||
else if (!HConnection.DECRYPTPACKETS) {
|
||||
else if (GEarthProperties.isPacketDecryptionDisabled()) {
|
||||
synchronized (sendLock) {
|
||||
out.write(buffer);
|
||||
}
|
||||
}
|
||||
else if (decryptcipher == null) {
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
tempEncryptedBuffer.add(buffer[i]);
|
||||
}
|
||||
for (byte b : buffer)
|
||||
tempEncryptedBuffer.add(b);
|
||||
}
|
||||
else {
|
||||
byte[] tm = decryptcipher.rc4(buffer);
|
||||
@ -162,9 +163,10 @@ public abstract class FlashPacketHandler extends PacketHandler {
|
||||
|
||||
protected abstract void printForDebugging(byte[] bytes);
|
||||
|
||||
private Observable<BufferChangeListener> bufferChangeObservable = new Observable<>(BufferChangeListener::act);
|
||||
public Observable<BufferChangeListener> getBufferChangeObservable() {
|
||||
return bufferChangeObservable;
|
||||
private final ObjectProperty<byte[]> incomingBufferProperty = new SimpleObjectProperty<>();
|
||||
|
||||
public ObjectProperty<byte[]> incomingBufferProperty() {
|
||||
return incomingBufferProperty;
|
||||
}
|
||||
|
||||
public int getCurrentIndex() {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package gearth.services.extension_handler;
|
||||
|
||||
import gearth.GEarth;
|
||||
import gearth.misc.HostInfo;
|
||||
import gearth.misc.listenerpattern.Observable;
|
||||
import gearth.protocol.HConnection;
|
||||
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.ExtensionProducerFactory;
|
||||
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 java.io.IOException;
|
||||
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 HConnection hConnection;
|
||||
@ -47,38 +47,13 @@ public class ExtensionHandler {
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
GEarth.getThemeObservable().addListener(theme -> {
|
||||
GEarthProperties.hostInfoBinding.addListener(((observable1, oldValue, newValue) -> {
|
||||
synchronized (gEarthExtensions) {
|
||||
for (GEarthExtension extension : gEarthExtensions) {
|
||||
extension.updateHostInfo(getHostInfo());
|
||||
}
|
||||
gEarthExtensions.forEach(extension -> extension.updateHostInfo(newValue));
|
||||
}
|
||||
});
|
||||
|
||||
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.forEach(extensionProducer -> extensionProducer.startProducing(createExtensionProducerObserver()));
|
||||
}
|
||||
@ -259,7 +234,7 @@ public class ExtensionHandler {
|
||||
extension.getClickedObservable().addListener(extension::doubleclick);
|
||||
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) {
|
||||
extension.connectionStart(
|
||||
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() {
|
||||
return extensionProducers;
|
||||
}
|
||||
@ -296,5 +261,26 @@ public class ExtensionHandler {
|
||||
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;
|
||||
|
||||
import gearth.GEarth;
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.misc.BindingsUtil;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.connection.HClient;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
||||
import gearth.services.Constants;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.translations.TranslatableString;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.ui.SubForm;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@ -22,11 +22,6 @@ import java.util.Set;
|
||||
|
||||
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> inpHost;
|
||||
public Button btnConnect;
|
||||
@ -40,7 +35,6 @@ public class ConnectionController extends SubForm {
|
||||
private volatile int fullyInitialized = 0;
|
||||
|
||||
|
||||
public static final String CLIENT_CACHE_KEY = "last_client_mode";
|
||||
public ToggleGroup tgl_clientMode;
|
||||
public RadioButton rd_unity;
|
||||
public RadioButton rd_flash;
|
||||
@ -59,38 +53,16 @@ public class ConnectionController extends SubForm {
|
||||
Constants.UNITY_PACKETS = rd_unity.isSelected();
|
||||
});
|
||||
|
||||
if (Cacher.getCacheContents().has(CLIENT_CACHE_KEY)) {
|
||||
switch (Cacher.getCacheContents().getEnum(HClient.class, CLIENT_CACHE_KEY)) {
|
||||
case FLASH:
|
||||
rd_flash.setSelected(true);
|
||||
break;
|
||||
case UNITY:
|
||||
rd_unity.setSelected(true);
|
||||
break;
|
||||
case NITRO:
|
||||
rd_nitro.setSelected(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GEarthProperties.clientTypeProperty
|
||||
.addListener((observable, oldValue, newValue) -> selectClientType(newValue));
|
||||
selectClientType(GEarthProperties.clientTypeProperty.getValue());
|
||||
|
||||
cbx_autodetect.selectedProperty().addListener(observable -> updateInputUI());
|
||||
inpPort.getEditor().textProperty().addListener(observable -> updateInputUI());
|
||||
|
||||
Object object;
|
||||
String hostRemember = null;
|
||||
String portRemember = null;
|
||||
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();
|
||||
});
|
||||
BindingsUtil.setAndBindBiDirectional(cbx_autodetect.selectedProperty(), GEarthProperties.autoDetectProperty);
|
||||
BindingsUtil.setAndBindBiDirectional(outHost.textProperty(), GEarthProperties.hostProperty);
|
||||
BindingsUtil.setAndBindBiDirectional(outPort.textProperty(), GEarthProperties.portProperty);
|
||||
|
||||
List<String> knownHosts = ProxyProviderFactory.autoDetectHosts;
|
||||
Set<String> hosts = new HashSet<>();
|
||||
@ -110,6 +82,8 @@ public class ConnectionController extends SubForm {
|
||||
|
||||
int hostSelectIndex = 0;
|
||||
int portSelectIndex = 0;
|
||||
final String hostRemember = GEarthProperties.hostProperty.get();
|
||||
final String portRemember = Integer.toString(GEarthProperties.portProperty.get());
|
||||
if (hostRemember != null) {
|
||||
hostSelectIndex = hostsSorted.indexOf(hostRemember);
|
||||
portSelectIndex = portsSorted.indexOf(portRemember);
|
||||
@ -138,15 +112,31 @@ public class ConnectionController extends SubForm {
|
||||
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() {
|
||||
if (parentController == null) return;
|
||||
|
||||
grd_clientSelection.setDisable(getHConnection().getState() != HState.NOT_CONNECTED);
|
||||
txtfield_hotelversion.setText(getHConnection().getHotelVersion());
|
||||
final HConnection hConnection = getHConnection();
|
||||
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()) {
|
||||
@ -159,15 +149,15 @@ public class ConnectionController extends SubForm {
|
||||
}
|
||||
}
|
||||
|
||||
inpHost.setDisable(getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpPort.setDisable(getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpHost.setDisable(hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpPort.setDisable(hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
|
||||
cbx_autodetect.setDisable(!useFlash());
|
||||
outHost.setDisable(!useFlash());
|
||||
outPort.setDisable(!useFlash());
|
||||
|
||||
inpHost.setDisable(!useFlash() || getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpPort.setDisable(!useFlash() || getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpHost.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpPort.setDisable(!useFlash() || hConnectionState != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
}
|
||||
|
||||
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();
|
||||
if (newState == HState.NOT_CONNECTED) {
|
||||
if (newValue == HState.NOT_CONNECTED) {
|
||||
state.setKey(0, "tab.connection.state.notconnected");
|
||||
connect.setKey(0, "tab.connection.button.connect");
|
||||
outHost.setText("");
|
||||
outPort.setText("");
|
||||
}
|
||||
else if (oldState == HState.NOT_CONNECTED) {
|
||||
else if (oldValue == HState.NOT_CONNECTED)
|
||||
connect.setKey(0, "tab.connection.button.abort");
|
||||
}
|
||||
|
||||
if (newState == HState.CONNECTED) {
|
||||
if (newValue == HState.CONNECTED)
|
||||
state.setKey(0, "tab.connection.state.connected");
|
||||
}
|
||||
if (newState == HState.WAITING_FOR_CLIENT) {
|
||||
if (newValue == HState.WAITING_FOR_CLIENT)
|
||||
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);
|
||||
@ -234,9 +215,11 @@ public class ConnectionController extends SubForm {
|
||||
String port = GEarth.getArgument("--port");
|
||||
if (host != null && port != null) {
|
||||
Platform.runLater(() -> {
|
||||
if (!inpHost.getItems().contains(host)) inpHost.getItems().add(host);
|
||||
if (!inpHost.getItems().contains(host))
|
||||
inpHost.getItems().add(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);
|
||||
cbx_autodetect.setSelected(false);
|
||||
});
|
||||
@ -275,12 +258,9 @@ public class ConnectionController extends SubForm {
|
||||
} else if (isClientMode(HClient.NITRO)) {
|
||||
getHConnection().startNitro();
|
||||
}
|
||||
|
||||
|
||||
if (HConnection.DEBUG) System.out.println("connecting");
|
||||
if (GEarthProperties.isDebugModeEnabled())
|
||||
System.out.println("connecting");
|
||||
}).start();
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
getHConnection().abort();
|
||||
@ -289,13 +269,10 @@ public class ConnectionController extends SubForm {
|
||||
|
||||
@Override
|
||||
protected void onExit() {
|
||||
if (rd_flash.isSelected()) {
|
||||
Cacher.put(CLIENT_CACHE_KEY, HClient.FLASH);
|
||||
} else if (rd_unity.isSelected()) {
|
||||
Cacher.put(CLIENT_CACHE_KEY, HClient.UNITY);
|
||||
} else if (rd_nitro.isSelected()) {
|
||||
Cacher.put(CLIENT_CACHE_KEY, HClient.NITRO);
|
||||
}
|
||||
GEarthProperties.clientTypeProperty.set(
|
||||
rd_flash.isSelected() ? HClient.FLASH
|
||||
: rd_unity.isSelected() ? HClient.UNITY
|
||||
: HClient.NITRO);
|
||||
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.ExtensionRunnerFactory;
|
||||
import gearth.services.g_python.GPythonShell;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.SubForm;
|
||||
import gearth.ui.subforms.extensions.logger.ExtensionLogger;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
@ -48,6 +49,8 @@ public class ExtensionsController extends SubForm {
|
||||
scroller.widthProperty().addListener(observable -> header_ext.setPrefWidth(scroller.getWidth()));
|
||||
extensionLogger = new ExtensionLogger();
|
||||
|
||||
btn_install.disableProperty().bind(GEarthProperties.enableDeveloperModeProperty.not());
|
||||
|
||||
initLanguageBinding();
|
||||
}
|
||||
|
||||
@ -79,8 +82,6 @@ public class ExtensionsController extends SubForm {
|
||||
extensionLogger.log(text);
|
||||
}
|
||||
}));
|
||||
|
||||
getHConnection().onDeveloperModeChange(this::setLocalInstallingEnabled);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
package gearth.ui.subforms.extra;
|
||||
|
||||
import gearth.GEarth;
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.misc.BindingsUtil;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
||||
import gearth.protocol.connection.proxy.SocksConfiguration;
|
||||
import gearth.services.always_admin.AdminService;
|
||||
import gearth.services.g_python.GPythonVersionUtils;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.SubForm;
|
||||
import gearth.ui.subforms.info.InfoController;
|
||||
import gearth.ui.titlebar.TitleBarController;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
import gearth.ui.translations.TranslatableString;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.FlowPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Region;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
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 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;
|
||||
|
||||
@ -69,32 +59,23 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
||||
url_troubleshooting.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting"));
|
||||
InfoController.activateHyperlink(url_troubleshooting);
|
||||
|
||||
String notepadInitValue = (String)Cacher.get(NOTEPAD_CACHE_KEY);
|
||||
if (notepadInitValue != null) {
|
||||
txtarea_notepad.setText(notepadInitValue);
|
||||
}
|
||||
BindingsUtil.setAndBindBiDirectional(txtarea_notepad.textProperty(), GEarthProperties.notesProperty);
|
||||
|
||||
if (Cacher.getCacheContents().has(SOCKS_CACHE_KEY)) {
|
||||
JSONObject socksInitValue = Cacher.getCacheContents().getJSONObject(SOCKS_CACHE_KEY);
|
||||
txt_socksIp.setText(socksInitValue.getString(SOCKS_IP) + ":" + socksInitValue.getInt(SOCKS_PORT));
|
||||
// cbx_socksUseIfNeeded.setSelected(socksInitValue.getBoolean(IGNORE_ONCE));
|
||||
}
|
||||
|
||||
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()));
|
||||
txt_socksIp.textProperty().set(GEarthProperties.getSocksHost()+":"+GEarthProperties.getSocksPort());
|
||||
GEarthProperties.socksHostProperty.bind(Bindings.createStringBinding(this::getSocksHost, txt_socksIp.textProperty()));
|
||||
GEarthProperties.socksPortProperty.bind(Bindings.createIntegerBinding(this::getSocksPort, txt_socksIp.textProperty()));
|
||||
grd_socksInfo.disableProperty().bind(GEarthProperties.enableSocksProperty.not());
|
||||
|
||||
BindingsUtil.setAndBindBiDirectional(cbx_useSocks.selectedProperty(), GEarthProperties.enableSocksProperty);
|
||||
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();
|
||||
}
|
||||
|
||||
@ -102,47 +83,16 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
||||
protected void onParentSet() {
|
||||
adminService = new AdminService(cbx_admin.isSelected(), getHConnection());
|
||||
getHConnection().addTrafficListener(1, message -> adminService.onMessage(message));
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> {if (newState == HState.CONNECTED) adminService.onConnect();});
|
||||
|
||||
parentController.getStage().setAlwaysOnTop(cbx_alwaysOnTop.isSelected());
|
||||
cbx_alwaysOnTop.selectedProperty().addListener(observable -> parentController.getStage().setAlwaysOnTop(cbx_alwaysOnTop.isSelected()));
|
||||
|
||||
cbx_advanced.selectedProperty().addListener(observable -> updateAdvancedUI());
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> {
|
||||
if (oldState == HState.NOT_CONNECTED || newState == HState.NOT_CONNECTED) {
|
||||
getHConnection().stateProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue == HState.CONNECTED)
|
||||
adminService.onConnect();
|
||||
if (oldValue == HState.NOT_CONNECTED || newValue == HState.NOT_CONNECTED)
|
||||
updateAdvancedUI();
|
||||
}
|
||||
});
|
||||
|
||||
if (Cacher.getCacheContents().has(DEVELOP_CACHE_KEY)) {
|
||||
boolean inDevelopMode = Cacher.getCacheContents().getBoolean(DEVELOP_CACHE_KEY);
|
||||
setDevelopMode(inDevelopMode);
|
||||
}
|
||||
|
||||
cbx_advanced.selectedProperty().addListener(observable -> 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() {
|
||||
if (!cbx_advanced.isSelected()) {
|
||||
cbx_debug.setSelected(false);
|
||||
@ -158,7 +108,6 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
||||
|
||||
@Override
|
||||
public boolean useSocks() {
|
||||
saveSocksConfig();
|
||||
return cbx_useSocks.isSelected();
|
||||
}
|
||||
|
||||
@ -265,7 +214,6 @@ public class ExtraController extends SubForm implements SocksConfiguration {
|
||||
|
||||
private void setDevelopMode(boolean enabled) {
|
||||
cbx_develop.setSelected(enabled);
|
||||
getHConnection().setDeveloperMode(enabled);
|
||||
}
|
||||
|
||||
public void adminCbxClick(ActionEvent actionEvent) {
|
||||
|
@ -1,23 +1,26 @@
|
||||
package gearth.ui.subforms.info;
|
||||
|
||||
import gearth.GEarth;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.titlebar.TitleBarController;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
import gearth.ui.translations.TranslatableString;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import gearth.ui.SubForm;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.web.WebView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 06/04/18.
|
||||
*/
|
||||
public class InfoController extends SubForm {
|
||||
public class InfoController extends SubForm implements Initializable {
|
||||
public ImageView img_logo;
|
||||
public Hyperlink link_darkbox;
|
||||
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_d_gearth.setTooltip(new Tooltip("https://discord.gg/AVkcF8y"));
|
||||
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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,14 @@ import gearth.misc.Cacher;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.HMessage;
|
||||
import gearth.protocol.HPacket;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.SubForm;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
import gearth.ui.translations.TranslatableString;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.MouseButton;
|
||||
@ -38,10 +42,10 @@ public class InjectionController extends SubForm {
|
||||
private TranslatableString corruption, pcktInfo;
|
||||
|
||||
protected void onParentSet() {
|
||||
getHConnection().onDeveloperModeChange(developMode -> updateUI());
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(this::updateUI));
|
||||
|
||||
inputPacket.textProperty().addListener(event -> Platform.runLater(this::updateUI));
|
||||
final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI);
|
||||
GEarthProperties.enableDeveloperModeProperty.addListener(updateUI);
|
||||
getHConnection().stateProperty().addListener(updateUI);
|
||||
inputPacket.textProperty().addListener(updateUI);
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
|
@ -9,6 +9,15 @@ import gearth.services.scheduler.listeners.OnBeingUpdatedListener;
|
||||
import gearth.services.scheduler.listeners.OnDeleteListener;
|
||||
import gearth.services.scheduler.listeners.OnEditListener;
|
||||
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 {
|
||||
|
||||
|
@ -7,9 +7,12 @@ import gearth.protocol.StateChangeListener;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.services.scheduler.Interval;
|
||||
import gearth.services.scheduler.Scheduler;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import gearth.ui.translations.LanguageBundle;
|
||||
import gearth.ui.translations.TranslatableString;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.GridPane;
|
||||
@ -88,8 +91,9 @@ public class SchedulerController extends SubForm {
|
||||
@Override
|
||||
protected void onParentSet() {
|
||||
scheduler = new Scheduler<>(getHConnection());
|
||||
getHConnection().onDeveloperModeChange(developMode -> updateUI());
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> updateUI());
|
||||
final InvalidationListener updateUI = observable -> Platform.runLater(this::updateUI);
|
||||
GEarthProperties.enableDeveloperModeProperty.addListener(updateUI);
|
||||
getHConnection().stateProperty().addListener(updateUI);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,13 @@
|
||||
package gearth.ui.titlebar;
|
||||
|
||||
import gearth.GEarth;
|
||||
import gearth.ui.themes.Theme;
|
||||
import gearth.ui.GEarthProperties;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class GEarthThemedTitleBarConfig extends DefaultTitleBarConfig {
|
||||
|
||||
public GEarthThemedTitleBarConfig(Stage stage) {
|
||||
super(stage, GEarth.getTheme());
|
||||
GEarth.getThemeObservable().addListener(this::setTheme);
|
||||
super(stage, GEarthProperties.getTheme());
|
||||
GEarthProperties.themeProperty.addListener((observable, oldValue, newValue) -> setTheme(newValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user