things and anime

This commit is contained in:
sirjonasxx 2020-12-25 00:17:54 +01:00
parent 3ed0575e05
commit 118e7587ac
9 changed files with 178 additions and 171 deletions

View File

@ -4,9 +4,9 @@ import gearth.misc.listenerpattern.Observable;
import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HProxy;
import gearth.protocol.connection.HState; import gearth.protocol.connection.HState;
import gearth.protocol.connection.proxy.ProxyProvider; import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.connection.proxy.flash.FlashProxyProvider;
import gearth.protocol.connection.proxy.ProxyProviderFactory; import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.unix.LinuxRawIpProxyProvider; import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
import gearth.protocol.connection.proxy.windows.WindowsRawIpProxyProvider;
import gearth.services.extensionhandler.ExtensionHandler; import gearth.services.extensionhandler.ExtensionHandler;
import java.io.IOException; import java.io.IOException;
@ -166,7 +166,7 @@ public class HConnection {
} }
public boolean isRawIpMode() { public boolean isRawIpMode() {
return proxyProvider != null && proxyProvider instanceof LinuxRawIpProxyProvider; return proxyProvider != null && proxyProvider instanceof LinuxRawIpFlashProxyProvider;
// WindowsRawIpProxyProvider extends LinuxRawIpProxyProvider // WindowsRawIpProxyProvider extends LinuxRawIpProxyProvider
} }

View File

@ -1,129 +1,10 @@
package gearth.protocol.connection.proxy; 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.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; void start() throws IOException;
protected final HStateSetter stateSetter; void abort();
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();
});
}
} }

View File

@ -5,8 +5,10 @@ import gearth.misc.OSValidator;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HStateSetter; import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.unix.LinuxRawIpProxyProvider; import gearth.protocol.connection.proxy.flash.NormalFlashProxyProvider;
import gearth.protocol.connection.proxy.windows.WindowsRawIpProxyProvider; 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.application.Platform;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
@ -67,7 +69,7 @@ public class ProxyProviderFactory {
// checks if host is a raw IP instead of a domain // checks if host is a raw IP instead of a domain
// TODO support ipv6 (not only here, also in IPmapper) // 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()) { for (char c : host.toCharArray()) {
if (c != '.' && (c < '0' || c > '9')) { if (c != '.' && (c < '0' || c > '9')) {
return false; return false;
@ -79,7 +81,6 @@ public class ProxyProviderFactory {
public ProxyProvider provide() { public ProxyProvider provide() {
return provide(autoDetectHosts); return provide(autoDetectHosts);
} }
public ProxyProvider provide(String domain, int port) { public ProxyProvider provide(String domain, int port) {
List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY); List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY);
if (additionalCachedHotels == null) { if (additionalCachedHotels == null) {
@ -92,12 +93,12 @@ public class ProxyProviderFactory {
if (hostIsIpAddress(domain)) { if (hostIsIpAddress(domain)) {
if (OSValidator.isWindows()) { if (OSValidator.isWindows()) {
if (WindowsRawIpProxyProvider.isNoneConnected(domain) && if (WindowsRawIpFlashProxyProvider.isNoneConnected(domain) &&
(!socksConfig.useSocks() || socksConfig.onlyUseIfNeeded()) ) { (!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()) { else if (socksConfig.useSocks()) {
return new WindowsRawIpProxyProvider(proxySetter, stateSetter, hConnection, domain, port, true); return new WindowsRawIpFlashProxyProvider(proxySetter, stateSetter, hConnection, domain, port, true);
} }
Platform.runLater(() -> { Platform.runLater(() -> {
@ -112,7 +113,7 @@ public class ProxyProviderFactory {
return null; return null;
} }
else if (OSValidator.isUnix() || OSValidator.isMac()) { 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; return null;
@ -123,9 +124,8 @@ public class ProxyProviderFactory {
return provide(potentialHost); return provide(potentialHost);
} }
} }
private ProxyProvider provide(List<String> potentialHosts) { private ProxyProvider provide(List<String> 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) { public static void setSocksConfig(SocksConfiguration configuration) {

View File

@ -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();
});
}
}

View File

@ -1,4 +1,4 @@
package gearth.protocol.connection.proxy; package gearth.protocol.connection.proxy.flash;
import gearth.misc.Cacher; import gearth.misc.Cacher;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
@ -6,16 +6,17 @@ import gearth.protocol.connection.HProxy;
import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HState; import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter; import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.SocksConfiguration;
import gearth.protocol.hostreplacer.hostsfile.HostReplacer; import gearth.protocol.hostreplacer.hostsfile.HostReplacer;
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory; import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
public class NormalProxyProvider extends ProxyProvider { public class NormalFlashProxyProvider extends FlashProxyProvider {
private List<String> potentialHosts; private List<String> potentialHosts;
@ -29,7 +30,7 @@ public class NormalProxyProvider extends ProxyProvider {
private boolean useSocks; private boolean useSocks;
public NormalProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, List<String> potentialHosts, boolean useSocks) { public NormalFlashProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, List<String> potentialHosts, boolean useSocks) {
super(proxySetter, stateSetter, hConnection); super(proxySetter, stateSetter, hConnection);
this.potentialHosts = potentialHosts; this.potentialHosts = potentialHosts;
this.useSocks = useSocks; this.useSocks = useSocks;

View File

@ -1,26 +1,22 @@
package gearth.protocol.connection.proxy.unix; package gearth.protocol.connection.proxy.flash.unix;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HProxy;
import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HState; import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter; import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider; import gearth.protocol.connection.proxy.flash.FlashProxyProvider;
import gearth.protocol.connection.proxy.ProxyProviderFactory; import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.SocksConfiguration; import gearth.protocol.connection.proxy.SocksConfiguration;
import gearth.protocol.hostreplacer.ipmapping.IpMapper; import gearth.protocol.hostreplacer.ipmapping.IpMapper;
import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory; 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.io.IOException;
import java.net.*; import java.net.*;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Queue; import java.util.Queue;
public class LinuxRawIpProxyProvider extends ProxyProvider { public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
private volatile String input_host; private volatile String input_host;
private volatile int input_port; private volatile int input_port;
@ -30,7 +26,7 @@ public class LinuxRawIpProxyProvider extends ProxyProvider {
private boolean useSocks; 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); super(proxySetter, stateSetter, hConnection);
this.input_host = input_host; this.input_host = input_host;
this.input_port = input_port; this.input_port = input_port;

View File

@ -1,35 +1,23 @@
package gearth.protocol.connection.proxy.windows; package gearth.protocol.connection.proxy.flash.windows;
import gearth.misc.Cacher; import gearth.misc.Cacher;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.connection.HProxy;
import gearth.protocol.connection.HProxySetter; import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HState; import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter; import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider; import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
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 org.json.JSONObject; import org.json.JSONObject;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.UUID; import java.util.UUID;
// windows raw ip proxy provider extends the Linux one with the exception that it does not want to close // windows raw ip proxy provider extends the Linux one with the exception that it does not want to close
// the IP redirect on connect // the IP redirect on connect
public class WindowsRawIpProxyProvider extends LinuxRawIpProxyProvider { public class WindowsRawIpFlashProxyProvider extends LinuxRawIpFlashProxyProvider {
private boolean hasMapped = false; 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); super(proxySetter, stateSetter, hConnection, input_host, input_port, useSocks);
} }

View File

@ -0,0 +1,4 @@
package gearth.protocol.connection.proxy.unity;
public class ProxyProvider {
}

View File

@ -27,7 +27,7 @@
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints maxHeight="7.0" minHeight="7.0" prefHeight="7.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="7.0" minHeight="7.0" prefHeight="7.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="34.0" minHeight="34.0" prefHeight="34.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="28.0" minHeight="28.0" prefHeight="28.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="28.0" minHeight="28.0" prefHeight="28.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="232.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="232.0" vgrow="SOMETIMES" />
@ -117,25 +117,32 @@
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
</CheckBox> </CheckBox>
<GridPane GridPane.rowIndex="1"> <GridPane prefHeight="26.0" prefWidth="286.0" style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="1">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="67.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="149.0" minWidth="10.0" prefWidth="38.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="242.0" minWidth="10.0" prefWidth="242.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="81.0" minWidth="69.0" prefWidth="75.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="83.0" minWidth="66.0" prefWidth="72.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="82.0" minWidth="61.0" prefWidth="65.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="242.0" minWidth="10.0" prefWidth="47.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="20.0" prefHeight="34.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<RadioButton fx:id="rd_unity" mnemonicParsing="false" selected="true" text="Unity"> <RadioButton fx:id="rd_unity" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" selected="true" text="Unity" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS">
<toggleGroup> <toggleGroup>
<ToggleGroup fx:id="tgl_clientMode" /> <ToggleGroup fx:id="tgl_clientMode" />
</toggleGroup> </toggleGroup>
</RadioButton> </RadioButton>
<RadioButton fx:id="rd_flash" mnemonicParsing="false" text="Flash" toggleGroup="$tgl_clientMode" GridPane.columnIndex="1" /> <RadioButton fx:id="rd_flash" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Flash" toggleGroup="$tgl_clientMode" GridPane.columnIndex="2" />
<RadioButton disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="Anime" GridPane.columnIndex="3" />
</children> </children>
<GridPane.margin> <GridPane.margin>
<Insets bottom="2.0" left="10.0" top="2.0" /> <Insets left="10.0" right="10.0" />
</GridPane.margin> </GridPane.margin>
<padding>
<Insets bottom="8.0" top="8.0" />
</padding>
</GridPane> </GridPane>
</children> </children>
<GridPane.margin> <GridPane.margin>