From 118e7587acfbfb895d37d6a59ddf40bcf3159922 Mon Sep 17 00:00:00 2001 From: sirjonasxx <36828922+sirjonasxx@users.noreply.github.com> Date: Fri, 25 Dec 2020 00:17:54 +0100 Subject: [PATCH] things and anime --- .../java/gearth/protocol/HConnection.java | 6 +- .../connection/proxy/ProxyProvider.java | 125 +---------------- .../proxy/ProxyProviderFactory.java | 20 +-- .../proxy/flash/FlashProxyProvider.java | 130 ++++++++++++++++++ .../NormalFlashProxyProvider.java} | 9 +- .../unix/LinuxRawIpFlashProxyProvider.java} | 12 +- .../WindowsRawIpFlashProxyProvider.java} | 20 +-- .../connection/proxy/unity/ProxyProvider.java | 4 + .../main/resources/gearth/ui/extra/Extra.fxml | 23 ++-- 9 files changed, 178 insertions(+), 171 deletions(-) create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java rename G-Earth/src/main/java/gearth/protocol/connection/proxy/{NormalProxyProvider.java => flash/NormalFlashProxyProvider.java} (95%) rename G-Earth/src/main/java/gearth/protocol/connection/proxy/{unix/LinuxRawIpProxyProvider.java => flash/unix/LinuxRawIpFlashProxyProvider.java} (92%) rename G-Earth/src/main/java/gearth/protocol/connection/proxy/{windows/WindowsRawIpProxyProvider.java => flash/windows/WindowsRawIpFlashProxyProvider.java} (84%) create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java diff --git a/G-Earth/src/main/java/gearth/protocol/HConnection.java b/G-Earth/src/main/java/gearth/protocol/HConnection.java index 1a84a6d..041e3dc 100644 --- a/G-Earth/src/main/java/gearth/protocol/HConnection.java +++ b/G-Earth/src/main/java/gearth/protocol/HConnection.java @@ -4,9 +4,9 @@ import gearth.misc.listenerpattern.Observable; import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HState; import gearth.protocol.connection.proxy.ProxyProvider; +import gearth.protocol.connection.proxy.flash.FlashProxyProvider; import gearth.protocol.connection.proxy.ProxyProviderFactory; -import gearth.protocol.connection.proxy.unix.LinuxRawIpProxyProvider; -import gearth.protocol.connection.proxy.windows.WindowsRawIpProxyProvider; +import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider; import gearth.services.extensionhandler.ExtensionHandler; import java.io.IOException; @@ -166,7 +166,7 @@ public class HConnection { } public boolean isRawIpMode() { - return proxyProvider != null && proxyProvider instanceof LinuxRawIpProxyProvider; + return proxyProvider != null && proxyProvider instanceof LinuxRawIpFlashProxyProvider; // WindowsRawIpProxyProvider extends LinuxRawIpProxyProvider } diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java index a1faa47..c3a831d 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java @@ -1,129 +1,10 @@ package gearth.protocol.connection.proxy; -import gearth.protocol.HConnection; -import gearth.protocol.connection.HProxy; -import gearth.protocol.connection.HProxySetter; -import gearth.protocol.connection.HState; -import gearth.protocol.connection.HStateSetter; -import gearth.protocol.memory.Rc4Obtainer; -import gearth.protocol.packethandler.IncomingPacketHandler; -import gearth.protocol.packethandler.OutgoingPacketHandler; -import gearth.protocol.packethandler.PacketHandler; -import javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; -import javafx.scene.layout.Region; - import java.io.IOException; -import java.net.Socket; -import java.util.Arrays; -import java.util.concurrent.Semaphore; -public abstract class ProxyProvider { +public interface ProxyProvider { - protected final HProxySetter proxySetter; - protected final HStateSetter stateSetter; - protected final HConnection hConnection; - - private Semaphore abortSemaphore = null; - - public ProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection){ - this.proxySetter = proxySetter; - this.stateSetter = stateSetter; - this.hConnection = hConnection; - } - - protected void startProxyThread(Socket client, Socket server, HProxy proxy) throws IOException, InterruptedException { - final boolean[] datastream = new boolean[1]; - server.setTcpNoDelay(true); - client.setTcpNoDelay(true); - - client.setSoTimeout(0); - server.setSoTimeout(0); - - if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort()); - Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection); - - OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler()); - IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables(), outgoingHandler, hConnection.getExtensionHandler()); - rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler); - - Semaphore abort = new Semaphore(0); - - outgoingHandler.addOnDatastreamConfirmedListener(hotelVersion -> { - incomingHandler.setAsDataStream(); - proxy.verifyProxy(incomingHandler, outgoingHandler, hotelVersion); - proxySetter.setProxy(proxy); - datastream[0] = true; - abortSemaphore = abort; - onConnect(); - }); - - handleInputStream(client, outgoingHandler, abort); - handleInputStream(server, incomingHandler, abort); - - // abort can be acquired as soon as one of the sockets is closed - abort.acquire(); - try { - if (!server.isClosed()) server.close(); - if (!client.isClosed()) client.close(); - if (HConnection.DEBUG) System.out.println("STOP"); - if (datastream[0]) { - onConnectEnd(); - }; - } - catch (IOException e) { - e.printStackTrace(); - } - } - - private void handleInputStream(Socket socket, PacketHandler packetHandler, Semaphore abort) { - new Thread(() -> { - try { - int readLength; - byte[] buffer = new byte[10000]; - while (!socket.isClosed() && - (hConnection.getState() == HState.WAITING_FOR_CLIENT || hConnection.getState() == HState.CONNECTED) && - (readLength = socket.getInputStream().read(buffer)) != -1) { - packetHandler.act(Arrays.copyOf(buffer, readLength)); - } - } - catch (IOException ignore) { -// System.err.println(packetHandler instanceof IncomingPacketHandler ? "incoming" : "outgoing"); -// ignore.printStackTrace(); - } finally { - abort.release(); - } - }).start(); - } - - - public abstract void start() throws IOException; - public void abort() { - if (abortSemaphore != null) { - abortSemaphore.release(); - } - else { - stateSetter.setState(HState.NOT_CONNECTED); - } - } - - protected void onConnect() { - stateSetter.setState(HState.CONNECTED); - } - protected void onConnectEnd() { - proxySetter.setProxy(null); - abortSemaphore = null; - stateSetter.setState(HState.NOT_CONNECTED); - } - - protected void showInvalidConnectionError() { - Platform.runLater(() -> { - Alert alert = new Alert(Alert.AlertType.ERROR, "You entered invalid connection information, G-Earth could not connect", ButtonType.OK); - alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); - alert.setResizable(false); - alert.show(); - }); - } + void start() throws IOException; + void abort(); } diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java index 9cbe29e..59eecb4 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java @@ -5,8 +5,10 @@ import gearth.misc.OSValidator; import gearth.protocol.HConnection; import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HStateSetter; -import gearth.protocol.connection.proxy.unix.LinuxRawIpProxyProvider; -import gearth.protocol.connection.proxy.windows.WindowsRawIpProxyProvider; +import gearth.protocol.connection.proxy.flash.NormalFlashProxyProvider; +import gearth.protocol.connection.proxy.flash.FlashProxyProvider; +import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider; +import gearth.protocol.connection.proxy.flash.windows.WindowsRawIpFlashProxyProvider; import javafx.application.Platform; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; @@ -67,7 +69,7 @@ public class ProxyProviderFactory { // checks if host is a raw IP instead of a domain // TODO support ipv6 (not only here, also in IPmapper) - static boolean hostIsIpAddress(String host){ + public static boolean hostIsIpAddress(String host){ for (char c : host.toCharArray()) { if (c != '.' && (c < '0' || c > '9')) { return false; @@ -79,7 +81,6 @@ public class ProxyProviderFactory { public ProxyProvider provide() { return provide(autoDetectHosts); } - public ProxyProvider provide(String domain, int port) { List additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY); if (additionalCachedHotels == null) { @@ -92,12 +93,12 @@ public class ProxyProviderFactory { if (hostIsIpAddress(domain)) { if (OSValidator.isWindows()) { - if (WindowsRawIpProxyProvider.isNoneConnected(domain) && + if (WindowsRawIpFlashProxyProvider.isNoneConnected(domain) && (!socksConfig.useSocks() || socksConfig.onlyUseIfNeeded()) ) { - return new WindowsRawIpProxyProvider(proxySetter, stateSetter, hConnection, domain, port, false); + return new WindowsRawIpFlashProxyProvider(proxySetter, stateSetter, hConnection, domain, port, false); } else if (socksConfig.useSocks()) { - return new WindowsRawIpProxyProvider(proxySetter, stateSetter, hConnection, domain, port, true); + return new WindowsRawIpFlashProxyProvider(proxySetter, stateSetter, hConnection, domain, port, true); } Platform.runLater(() -> { @@ -112,7 +113,7 @@ public class ProxyProviderFactory { return null; } else if (OSValidator.isUnix() || OSValidator.isMac()) { - return new LinuxRawIpProxyProvider(proxySetter, stateSetter, hConnection, domain, port, socksConfig.useSocks() && !socksConfig.onlyUseIfNeeded()); + return new LinuxRawIpFlashProxyProvider(proxySetter, stateSetter, hConnection, domain, port, socksConfig.useSocks() && !socksConfig.onlyUseIfNeeded()); } return null; @@ -123,9 +124,8 @@ public class ProxyProviderFactory { return provide(potentialHost); } } - private ProxyProvider provide(List potentialHosts) { - return new NormalProxyProvider(proxySetter, stateSetter, hConnection, potentialHosts, socksConfig.useSocks() && !socksConfig.onlyUseIfNeeded()); + return new NormalFlashProxyProvider(proxySetter, stateSetter, hConnection, potentialHosts, socksConfig.useSocks() && !socksConfig.onlyUseIfNeeded()); } public static void setSocksConfig(SocksConfiguration configuration) { diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java new file mode 100644 index 0000000..0c69c33 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java @@ -0,0 +1,130 @@ +package gearth.protocol.connection.proxy.flash; + +import gearth.protocol.HConnection; +import gearth.protocol.connection.HProxy; +import gearth.protocol.connection.HProxySetter; +import gearth.protocol.connection.HState; +import gearth.protocol.connection.HStateSetter; +import gearth.protocol.connection.proxy.ProxyProvider; +import gearth.protocol.memory.Rc4Obtainer; +import gearth.protocol.packethandler.IncomingPacketHandler; +import gearth.protocol.packethandler.OutgoingPacketHandler; +import gearth.protocol.packethandler.PacketHandler; +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.layout.Region; + +import java.io.IOException; +import java.net.Socket; +import java.util.Arrays; +import java.util.concurrent.Semaphore; + +public abstract class FlashProxyProvider implements ProxyProvider { + + protected final HProxySetter proxySetter; + protected final HStateSetter stateSetter; + protected final HConnection hConnection; + + private Semaphore abortSemaphore = null; + + public FlashProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection){ + this.proxySetter = proxySetter; + this.stateSetter = stateSetter; + this.hConnection = hConnection; + } + + protected void startProxyThread(Socket client, Socket server, HProxy proxy) throws IOException, InterruptedException { + final boolean[] datastream = new boolean[1]; + server.setTcpNoDelay(true); + client.setTcpNoDelay(true); + + client.setSoTimeout(0); + server.setSoTimeout(0); + + if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort()); + Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection); + + OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler()); + IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables(), outgoingHandler, hConnection.getExtensionHandler()); + rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler); + + Semaphore abort = new Semaphore(0); + + outgoingHandler.addOnDatastreamConfirmedListener(hotelVersion -> { + incomingHandler.setAsDataStream(); + proxy.verifyProxy(incomingHandler, outgoingHandler, hotelVersion); + proxySetter.setProxy(proxy); + datastream[0] = true; + abortSemaphore = abort; + onConnect(); + }); + + handleInputStream(client, outgoingHandler, abort); + handleInputStream(server, incomingHandler, abort); + + // abort can be acquired as soon as one of the sockets is closed + abort.acquire(); + try { + if (!server.isClosed()) server.close(); + if (!client.isClosed()) client.close(); + if (HConnection.DEBUG) System.out.println("STOP"); + if (datastream[0]) { + onConnectEnd(); + }; + } + catch (IOException e) { + e.printStackTrace(); + } + } + + private void handleInputStream(Socket socket, PacketHandler packetHandler, Semaphore abort) { + new Thread(() -> { + try { + int readLength; + byte[] buffer = new byte[10000]; + while (!socket.isClosed() && + (hConnection.getState() == HState.WAITING_FOR_CLIENT || hConnection.getState() == HState.CONNECTED) && + (readLength = socket.getInputStream().read(buffer)) != -1) { + packetHandler.act(Arrays.copyOf(buffer, readLength)); + } + } + catch (IOException ignore) { +// System.err.println(packetHandler instanceof IncomingPacketHandler ? "incoming" : "outgoing"); +// ignore.printStackTrace(); + } finally { + abort.release(); + } + }).start(); + } + + + public abstract void start() throws IOException; + public void abort() { + if (abortSemaphore != null) { + abortSemaphore.release(); + } + else { + stateSetter.setState(HState.NOT_CONNECTED); + } + } + + protected void onConnect() { + stateSetter.setState(HState.CONNECTED); + } + protected void onConnectEnd() { + proxySetter.setProxy(null); + abortSemaphore = null; + stateSetter.setState(HState.NOT_CONNECTED); + } + + protected void showInvalidConnectionError() { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.ERROR, "You entered invalid connection information, G-Earth could not connect", ButtonType.OK); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.setResizable(false); + alert.show(); + }); + } + +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/NormalFlashProxyProvider.java similarity index 95% rename from G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java rename to G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/NormalFlashProxyProvider.java index 1d9499d..e52cdc3 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/NormalFlashProxyProvider.java @@ -1,4 +1,4 @@ -package gearth.protocol.connection.proxy; +package gearth.protocol.connection.proxy.flash; import gearth.misc.Cacher; import gearth.protocol.HConnection; @@ -6,16 +6,17 @@ import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HState; import gearth.protocol.connection.HStateSetter; +import gearth.protocol.connection.proxy.ProxyProviderFactory; +import gearth.protocol.connection.proxy.SocksConfiguration; import gearth.protocol.hostreplacer.hostsfile.HostReplacer; import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory; import java.io.IOException; import java.net.*; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -public class NormalProxyProvider extends ProxyProvider { +public class NormalFlashProxyProvider extends FlashProxyProvider { private List potentialHosts; @@ -29,7 +30,7 @@ public class NormalProxyProvider extends ProxyProvider { private boolean useSocks; - public NormalProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, List potentialHosts, boolean useSocks) { + public NormalFlashProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, List potentialHosts, boolean useSocks) { super(proxySetter, stateSetter, hConnection); this.potentialHosts = potentialHosts; this.useSocks = useSocks; diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unix/LinuxRawIpProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/unix/LinuxRawIpFlashProxyProvider.java similarity index 92% rename from G-Earth/src/main/java/gearth/protocol/connection/proxy/unix/LinuxRawIpProxyProvider.java rename to G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/unix/LinuxRawIpFlashProxyProvider.java index 23ac486..e5acd88 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unix/LinuxRawIpProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/unix/LinuxRawIpFlashProxyProvider.java @@ -1,26 +1,22 @@ -package gearth.protocol.connection.proxy.unix; +package gearth.protocol.connection.proxy.flash.unix; import gearth.protocol.HConnection; import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HState; import gearth.protocol.connection.HStateSetter; -import gearth.protocol.connection.proxy.ProxyProvider; +import gearth.protocol.connection.proxy.flash.FlashProxyProvider; 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 javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; -import javafx.scene.layout.Region; import java.io.IOException; import java.net.*; import java.util.LinkedList; import java.util.Queue; -public class LinuxRawIpProxyProvider extends ProxyProvider { +public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider { private volatile String input_host; private volatile int input_port; @@ -30,7 +26,7 @@ public class LinuxRawIpProxyProvider extends ProxyProvider { private boolean useSocks; - public LinuxRawIpProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, String input_host, int input_port, boolean useSocks) { + public LinuxRawIpFlashProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, String input_host, int input_port, boolean useSocks) { super(proxySetter, stateSetter, hConnection); this.input_host = input_host; this.input_port = input_port; diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/windows/WindowsRawIpProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/windows/WindowsRawIpFlashProxyProvider.java similarity index 84% rename from G-Earth/src/main/java/gearth/protocol/connection/proxy/windows/WindowsRawIpProxyProvider.java rename to G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/windows/WindowsRawIpFlashProxyProvider.java index 9d28d5d..2f5b748 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/windows/WindowsRawIpProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/windows/WindowsRawIpFlashProxyProvider.java @@ -1,35 +1,23 @@ -package gearth.protocol.connection.proxy.windows; +package gearth.protocol.connection.proxy.flash.windows; import gearth.misc.Cacher; import gearth.protocol.HConnection; -import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HState; import gearth.protocol.connection.HStateSetter; -import gearth.protocol.connection.proxy.ProxyProvider; -import gearth.protocol.connection.proxy.unix.LinuxRawIpProxyProvider; -import gearth.protocol.hostreplacer.ipmapping.IpMapper; -import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory; -import javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; -import javafx.scene.layout.Region; +import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider; import org.json.JSONObject; -import java.io.IOException; import java.math.BigInteger; -import java.net.*; -import java.util.LinkedList; -import java.util.Queue; import java.util.UUID; // windows raw ip proxy provider extends the Linux one with the exception that it does not want to close // the IP redirect on connect -public class WindowsRawIpProxyProvider extends LinuxRawIpProxyProvider { +public class WindowsRawIpFlashProxyProvider extends LinuxRawIpFlashProxyProvider { private boolean hasMapped = false; - public WindowsRawIpProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, String input_host, int input_port, boolean useSocks) { + public WindowsRawIpFlashProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, String input_host, int input_port, boolean useSocks) { super(proxySetter, stateSetter, hConnection, input_host, input_port, useSocks); } diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java new file mode 100644 index 0000000..9f3daed --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java @@ -0,0 +1,4 @@ +package gearth.protocol.connection.proxy.unity; + +public class ProxyProvider { +} diff --git a/G-Earth/src/main/resources/gearth/ui/extra/Extra.fxml b/G-Earth/src/main/resources/gearth/ui/extra/Extra.fxml index d84f2ff..0a2cdab 100644 --- a/G-Earth/src/main/resources/gearth/ui/extra/Extra.fxml +++ b/G-Earth/src/main/resources/gearth/ui/extra/Extra.fxml @@ -27,7 +27,7 @@ - + @@ -117,25 +117,32 @@ - + - - + + + + + - + - + - + + - + + + +