Developer mode and unsafe packet protection (wip)

This commit is contained in:
sirjonasxx 2022-12-27 22:39:32 +01:00
parent f98ea5385e
commit 7912fa35a6
17 changed files with 268 additions and 48 deletions

View File

@ -1,6 +1,8 @@
package gearth.protocol; package gearth.protocol;
import gearth.misc.listenerpattern.Observable; import gearth.misc.listenerpattern.Observable;
import gearth.protocol.connection.packetsafety.PacketSafetyManager;
import gearth.protocol.connection.packetsafety.SafePacketsContainer;
import gearth.protocol.connection.proxy.nitro.NitroProxyProvider; import gearth.protocol.connection.proxy.nitro.NitroProxyProvider;
import gearth.services.packet_info.PacketInfoManager; import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.connection.HClient; import gearth.protocol.connection.HClient;
@ -30,6 +32,8 @@ public class HConnection {
private ProxyProviderFactory proxyProviderFactory; private ProxyProviderFactory proxyProviderFactory;
private ProxyProvider proxyProvider = null; private ProxyProvider proxyProvider = null;
private volatile boolean developerMode = false;
public HConnection() { public HConnection() {
HConnection selff = this; HConnection selff = this;
proxyProviderFactory = new ProxyProviderFactory( proxyProviderFactory = new ProxyProviderFactory(
@ -37,6 +41,8 @@ public class HConnection {
selff::setState, selff::setState,
this this
); );
PacketSafetyManager.PACKET_SAFETY_MANAGER.initialize(this);
} }
public HState getState() { public HState getState() {
@ -147,30 +153,47 @@ public class HConnection {
public boolean sendToClient(HPacket packet) { public boolean sendToClient(HPacket packet) {
HProxy proxy = this.proxy; if (!canSendPacket(HMessage.Direction.TOCLIENT, packet)) return false;
if (proxy == null) return false;
if (!packet.isPacketComplete()) {
PacketInfoManager packetInfoManager = getPacketInfoManager();
packet.completePacket(packetInfoManager);
if (!packet.isPacketComplete() || !packet.canSendToClient()) return false;
}
return proxy.sendToClient(packet); return proxy.sendToClient(packet);
} }
public boolean sendToServer(HPacket packet) { public boolean sendToServer(HPacket packet) {
if (!canSendPacket(HMessage.Direction.TOSERVER, packet)) return false;
return proxy.sendToServer(packet);
}
private boolean canSendPacket(HMessage.Direction direction, HPacket packet) {
return isPacketSendingAllowed(direction, packet) && (developerMode || isPacketSendingSafe(direction, packet));
}
public boolean isPacketSendingAllowed(HMessage.Direction direction, HPacket packet) {
HProxy proxy = this.proxy; HProxy proxy = this.proxy;
if (proxy == null) return false; if (proxy == null) return false;
if (packet.isCorrupted()) return false;
if (!packet.isPacketComplete()) { if (!packet.isPacketComplete()) {
PacketInfoManager packetInfoManager = getPacketInfoManager(); PacketInfoManager packetInfoManager = getPacketInfoManager();
packet.completePacket(packetInfoManager); packet.completePacket(packetInfoManager);
if (!packet.isPacketComplete() || !packet.canSendToServer()) return false; return packet.isPacketComplete() &&
(packet.canSendToClient() || direction != HMessage.Direction.TOCLIENT) &&
(packet.canSendToServer() || direction != HMessage.Direction.TOSERVER);
} }
return proxy.sendToServer(packet); return true;
}
public boolean isPacketSendingSafe(HMessage.Direction direction, HPacket packet) {
String hotelVersion = proxy.getHotelVersion();
if (hotelVersion == null) return false;
SafePacketsContainer packetsContainer = PacketSafetyManager.PACKET_SAFETY_MANAGER.getPacketContainer(hotelVersion);
return packetsContainer.isPacketSafe(packet.headerId(), direction);
}
public void setDeveloperMode(boolean developerMode) {
this.developerMode = developerMode;
} }
public String getClientHost() { public String getClientHost() {
@ -205,7 +228,7 @@ public class HConnection {
if (proxy == null) { if (proxy == null) {
return null; return null;
} }
return proxy.gethClient(); return proxy.getHClient();
} }
public PacketInfoManager getPacketInfoManager() { public PacketInfoManager getPacketInfoManager() {

View File

@ -1,6 +1,9 @@
package gearth.protocol.connection; package gearth.protocol.connection;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;
import gearth.protocol.connection.packetsafety.PacketSafetyManager;
import gearth.protocol.connection.packetsafety.SafePacketsContainer;
import gearth.services.packet_info.PacketInfo;
import gearth.services.packet_info.PacketInfoManager; import gearth.services.packet_info.PacketInfoManager;
import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.PacketHandler;
@ -45,6 +48,11 @@ public class HProxy {
this.hotelVersion = hotelVersion; this.hotelVersion = hotelVersion;
this.clientIdentifier = clientIdentifier; this.clientIdentifier = clientIdentifier;
this.packetInfoManager = PacketInfoManager.fromHotelVersion(hotelVersion, hClient); this.packetInfoManager = PacketInfoManager.fromHotelVersion(hotelVersion, hClient);
SafePacketsContainer packetsContainer = PacketSafetyManager.PACKET_SAFETY_MANAGER.getPacketContainer(hotelVersion);
for (PacketInfo packetInfo : packetInfoManager.getPacketInfoList()) {
packetsContainer.validateSafePacket(packetInfo.getHeaderId(), packetInfo.getDestination());
}
} }
public boolean sendToServer(HPacket packet) { public boolean sendToServer(HPacket packet) {
@ -101,7 +109,7 @@ public class HProxy {
return hotelVersion; return hotelVersion;
} }
public HClient gethClient() { public HClient getHClient() {
return hClient; return hClient;
} }

View File

@ -0,0 +1,32 @@
package gearth.protocol.connection.packetsafety;
import gearth.protocol.HConnection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class PacketSafetyManager {
public static final PacketSafetyManager PACKET_SAFETY_MANAGER = new PacketSafetyManager();
private final Map<String, SafePacketsContainer> safePacketContainers = new ConcurrentHashMap<>();
private PacketSafetyManager() {
}
public void initialize(HConnection connection) {
connection.addTrafficListener(0, message -> {
String hotelVersion = connection.getHotelVersion();
if (hotelVersion.equals("")) return;
SafePacketsContainer safePacketsContainer = getPacketContainer(hotelVersion);
safePacketsContainer.validateSafePacket(message.getPacket().headerId(), message.getDestination());
});
}
public SafePacketsContainer getPacketContainer(String hotelVersion) {
return safePacketContainers.computeIfAbsent(hotelVersion, v -> new SafePacketsContainer());
}
}

View File

@ -0,0 +1,24 @@
package gearth.protocol.connection.packetsafety;
import gearth.protocol.HMessage;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class SafePacketsContainer {
private final Set<Integer> safeIncomingIds = Collections.synchronizedSet(new HashSet<>());
private final Set<Integer> safeOutgoingIds = Collections.synchronizedSet(new HashSet<>());
public void validateSafePacket(int headerId, HMessage.Direction direction) {
Set<Integer> headerIds = direction == HMessage.Direction.TOCLIENT ? safeIncomingIds : safeOutgoingIds;
headerIds.add(headerId);
}
public boolean isPacketSafe(int headerId, HMessage.Direction direction) {
Set<Integer> headerIds = direction == HMessage.Direction.TOCLIENT ? safeIncomingIds : safeOutgoingIds;
return headerIds.contains(headerId);
}
}

View File

@ -113,6 +113,10 @@ public class ExtensionsController extends SubForm {
} }
} }
public void setLocalInstallingEnabled(boolean enabled) {
btn_install.setDisable(!enabled);
}
private volatile int gpytonShellCounter = 1; private volatile int gpytonShellCounter = 1;
private volatile boolean pythonShellLaunching = false; private volatile boolean pythonShellLaunching = false;

View File

@ -16,14 +16,13 @@ import gearth.ui.translations.TranslatableString;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.stage.Stage;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
/** /**
* Created by Jonas on 06/04/18. * Created by Jonas on 06/04/18.
@ -33,6 +32,7 @@ public class ExtraController extends SubForm implements SocksConfiguration {
public static final String INFO_URL_GPYTHON = "https://github.com/sirjonasxx/G-Earth/wiki/G-Python-qtConsole"; public static final String INFO_URL_GPYTHON = "https://github.com/sirjonasxx/G-Earth/wiki/G-Python-qtConsole";
public static final String NOTEPAD_CACHE_KEY = "notepad_text"; public static final String 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 ALWAYS_ADMIN_KEY = "always_admin";
public static final String SOCKS_CACHE_KEY = "socks_config"; public static final String SOCKS_CACHE_KEY = "socks_config";
public static final String GPYTHON_CACHE_KEY = "use_gpython"; public static final String GPYTHON_CACHE_KEY = "use_gpython";
@ -58,10 +58,10 @@ public class ExtraController extends SubForm implements SocksConfiguration {
public CheckBox cbx_useSocks; public CheckBox cbx_useSocks;
public GridPane grd_socksInfo; public GridPane grd_socksInfo;
public TextField txt_socksPort;
public TextField txt_socksIp; public TextField txt_socksIp;
public CheckBox cbx_admin; public CheckBox cbx_admin;
public Label lbl_notepad, lbl_proxyIp, lbl_proxyPort; public Label lbl_notepad, lbl_proxyIp;
public CheckBox cbx_develop;
private AdminService adminService; private AdminService adminService;
@ -76,8 +76,7 @@ public class ExtraController extends SubForm implements SocksConfiguration {
if (Cacher.getCacheContents().has(SOCKS_CACHE_KEY)) { if (Cacher.getCacheContents().has(SOCKS_CACHE_KEY)) {
JSONObject socksInitValue = Cacher.getCacheContents().getJSONObject(SOCKS_CACHE_KEY); JSONObject socksInitValue = Cacher.getCacheContents().getJSONObject(SOCKS_CACHE_KEY);
txt_socksIp.setText(socksInitValue.getString(SOCKS_IP)); txt_socksIp.setText(socksInitValue.getString(SOCKS_IP) + ":" + socksInitValue.getInt(SOCKS_PORT));
txt_socksPort.setText(socksInitValue.getString(SOCKS_PORT));
// cbx_socksUseIfNeeded.setSelected(socksInitValue.getBoolean(IGNORE_ONCE)); // cbx_socksUseIfNeeded.setSelected(socksInitValue.getBoolean(IGNORE_ONCE));
} }
@ -115,6 +114,11 @@ public class ExtraController extends SubForm implements SocksConfiguration {
} }
}); });
if (Cacher.getCacheContents().has(DEVELOP_CACHE_KEY)) {
boolean inDevelopMode = Cacher.getCacheContents().getBoolean(DEVELOP_CACHE_KEY);
setDevelopMode(inDevelopMode);
}
updateAdvancedUI(); updateAdvancedUI();
} }
@ -123,13 +127,14 @@ public class ExtraController extends SubForm implements SocksConfiguration {
Cacher.put(NOTEPAD_CACHE_KEY, txtarea_notepad.getText()); Cacher.put(NOTEPAD_CACHE_KEY, txtarea_notepad.getText());
Cacher.put(GPYTHON_CACHE_KEY, cbx_gpython.isSelected()); Cacher.put(GPYTHON_CACHE_KEY, cbx_gpython.isSelected());
Cacher.put(ALWAYS_ADMIN_KEY, cbx_admin.isSelected()); Cacher.put(ALWAYS_ADMIN_KEY, cbx_admin.isSelected());
Cacher.put(DEVELOP_CACHE_KEY, cbx_develop.isSelected());
saveSocksConfig(); saveSocksConfig();
} }
private void saveSocksConfig() { private void saveSocksConfig() {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put(SOCKS_IP, txt_socksIp.getText()); jsonObject.put(SOCKS_IP, getSocksHost());
jsonObject.put(SOCKS_PORT, txt_socksPort.getText()); jsonObject.put(SOCKS_PORT, getSocksPort());
// jsonObject.put(IGNORE_ONCE, cbx_socksUseIfNeeded.isSelected()); // jsonObject.put(IGNORE_ONCE, cbx_socksUseIfNeeded.isSelected());
Cacher.put(SOCKS_CACHE_KEY, jsonObject); Cacher.put(SOCKS_CACHE_KEY, jsonObject);
} }
@ -155,12 +160,12 @@ public class ExtraController extends SubForm implements SocksConfiguration {
@Override @Override
public int getSocksPort() { public int getSocksPort() {
return Integer.parseInt(txt_socksPort.getText()); return Integer.parseInt(txt_socksIp.getText().split(":")[1]);
} }
@Override @Override
public String getSocksHost() { public String getSocksHost() {
return txt_socksIp.getText(); return txt_socksIp.getText().split(":")[0];
} }
@Override @Override
@ -221,9 +226,43 @@ public class ExtraController extends SubForm implements SocksConfiguration {
} }
public void developCbxClick(ActionEvent actionEvent) {
if (cbx_develop.isSelected()) {
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("tab.extra.options.developmode.alert.title"), ButtonType.NO, ButtonType.YES);
alert.setTitle(LanguageBundle.get("tab.extra.options.developmode.alert.title"));
Label lbl = new Label(LanguageBundle.get("tab.extra.options.developmode.alert.content"));
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
alert.getDialogPane().setContent(lbl);
try {
Optional<ButtonType> result = TitleBarController.create(alert).showAlertAndWait();
if (!result.isPresent() || result.get() == ButtonType.NO) {
cbx_develop.setSelected(false);
}
else {
setDevelopMode(true);
}
} catch (IOException e) {
e.printStackTrace();
}
});
}
else {
setDevelopMode(false);
}
}
private void setDevelopMode(boolean enabled) {
cbx_develop.setSelected(enabled);
getHConnection().setDeveloperMode(enabled);
parentController.extensionsController.setLocalInstallingEnabled(enabled);
}
public void adminCbxClick(ActionEvent actionEvent) { public void adminCbxClick(ActionEvent actionEvent) {
adminService.setEnabled(cbx_admin.isSelected()); adminService.setEnabled(cbx_admin.isSelected());
} }
private void initLanguageBinding() { private void initLanguageBinding() {
@ -231,10 +270,10 @@ public class ExtraController extends SubForm implements SocksConfiguration {
lbl_notepad.textProperty().bind(new TranslatableString("%s:", "tab.extra.notepad")); lbl_notepad.textProperty().bind(new TranslatableString("%s:", "tab.extra.notepad"));
lbl_proxyIp.textProperty().bind(new TranslatableString("%s:", "tab.extra.options.advanced.proxy.ip")); lbl_proxyIp.textProperty().bind(new TranslatableString("%s:", "tab.extra.options.advanced.proxy.ip"));
lbl_proxyPort.textProperty().bind(new TranslatableString("%s:", "tab.extra.options.advanced.proxy.port"));
cbx_alwaysOnTop.textProperty().bind(new TranslatableString("%s", "tab.extra.options.alwaysontop")); cbx_alwaysOnTop.textProperty().bind(new TranslatableString("%s", "tab.extra.options.alwaysontop"));
cbx_develop.textProperty().bind(new TranslatableString("%s", "tab.extra.options.developmode"));
cbx_admin.textProperty().bind(new TranslatableString("%s", "tab.extra.options.staffpermissions")); cbx_admin.textProperty().bind(new TranslatableString("%s", "tab.extra.options.staffpermissions"));
cbx_gpython.textProperty().bind(new TranslatableString("%s", "tab.extra.options.pythonscripting")); cbx_gpython.textProperty().bind(new TranslatableString("%s", "tab.extra.options.pythonscripting"));
cbx_advanced.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced")); cbx_advanced.textProperty().bind(new TranslatableString("%s", "tab.extra.options.advanced"));

View File

@ -4,7 +4,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.subforms.extensions.ExtensionsController"> <GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.subforms.extensions.ExtensionsController">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="277.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="277.0" />
</columnConstraints> </columnConstraints>
@ -72,7 +72,7 @@
<Insets left="3.0" /> <Insets left="3.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<Button fx:id="btn_install" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#installBtnClicked" text="Install" GridPane.columnIndex="5" /> <Button fx:id="btn_install" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#installBtnClicked" text="Install" GridPane.columnIndex="5" />
<Button fx:id="btn_viewExtensionConsole" layoutX="401.0" layoutY="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#extConsoleBtnClicked" text="View logs" GridPane.columnIndex="4" /> <Button fx:id="btn_viewExtensionConsole" layoutX="401.0" layoutY="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#extConsoleBtnClicked" text="View logs" GridPane.columnIndex="4" />
</GridPane> </GridPane>
</GridPane> </GridPane>

View File

@ -3,8 +3,9 @@
<?import javafx.geometry.*?> <?import javafx.geometry.*?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="650.0" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.subforms.extra.ExtraController"> <GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gearth.ui.subforms.extra.ExtraController">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="331.0" minWidth="10.0" prefWidth="318.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="331.0" minWidth="10.0" prefWidth="318.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="10.0" prefWidth="247.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="10.0" prefWidth="247.0" />
@ -30,16 +31,17 @@
<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="28.0" minHeight="28.0" prefHeight="28.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="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" />
</rowConstraints> </rowConstraints>
<children> <children>
<GridPane fx:id="grd_advanced" disable="true" prefHeight="161.0" prefWidth="299.0" style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="4"> <GridPane fx:id="grd_advanced" disable="true" prefHeight="161.0" prefWidth="299.0" style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="5">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<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="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="29.0" minHeight="29.0" prefHeight="29.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="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
@ -58,7 +60,7 @@
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="29.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />
@ -69,25 +71,15 @@
<children> <children>
<GridPane prefHeight="119.0" prefWidth="259.0"> <GridPane prefHeight="119.0" prefWidth="259.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="159.0" minWidth="10.0" prefWidth="68.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="159.0" minWidth="10.0" prefWidth="72.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="193.0" minWidth="10.0" prefWidth="145.0" /> <ColumnConstraints hgrow="SOMETIMES" maxWidth="240.0" minWidth="10.0" prefWidth="213.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints maxHeight="2.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="2.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="29.0" minHeight="29.0" prefHeight="29.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label fx:id="lbl_proxyIp" text="Proxy IP:" /> <Label fx:id="lbl_proxyIp" text="Proxy IP:" />
<Label fx:id="lbl_proxyPort" text="Proxy port:" GridPane.rowIndex="1" /> <TextField fx:id="txt_socksIp" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="ip:port" GridPane.columnIndex="1">
<TextField fx:id="txt_socksPort" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.rowIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets bottom="3.0" right="7.0" top="3.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="txt_socksIp" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1">
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets />
</opaqueInsets> </opaqueInsets>
@ -104,7 +96,7 @@
</GridPane> </GridPane>
</children> </children>
</GridPane> </GridPane>
<CheckBox fx:id="cbx_advanced" mnemonicParsing="false" text="Advanced" textFill="#000000ba" GridPane.rowIndex="3"> <CheckBox fx:id="cbx_advanced" mnemonicParsing="false" text="Advanced" textFill="#000000ba" GridPane.rowIndex="4">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
@ -112,16 +104,24 @@
<Insets top="2.0" /> <Insets top="2.0" />
</padding> </padding>
</CheckBox> </CheckBox>
<CheckBox fx:id="cbx_gpython" mnemonicParsing="false" onAction="#gpythonCbxClick" text="G-Python scripting" textFill="#000000ba" GridPane.rowIndex="2"> <CheckBox fx:id="cbx_gpython" mnemonicParsing="false" onAction="#gpythonCbxClick" text="G-Python scripting" textFill="#000000ba" GridPane.rowIndex="3">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
</CheckBox> </CheckBox>
<CheckBox fx:id="cbx_admin" layoutX="20.0" layoutY="25.0" mnemonicParsing="false" onAction="#adminCbxClick" selected="true" text="Client-side staff permissions" textFill="#000000ba" GridPane.rowIndex="1"> <CheckBox fx:id="cbx_admin" layoutX="20.0" layoutY="25.0" mnemonicParsing="false" onAction="#adminCbxClick" selected="true" text="Client-side staff permissions" textFill="#000000ba" GridPane.rowIndex="2">
<GridPane.margin> <GridPane.margin>
<Insets left="10.0" top="2.0" /> <Insets left="10.0" top="2.0" />
</GridPane.margin> </GridPane.margin>
</CheckBox> </CheckBox>
<CheckBox fx:id="cbx_develop" layoutX="20.0" layoutY="52.0" mnemonicParsing="false" onAction="#developCbxClick" text="Developer mode" textFill="#000000ba" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
<font>
<Font name="System Bold" size="12.0" />
</font>
</CheckBox>
</children> </children>
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />

View File

@ -97,6 +97,16 @@ tab.extra=Extras
tab.extra.notepad=Notepad tab.extra.notepad=Notepad
tab.extra.troubleshooting=Fehlerbehebungen tab.extra.troubleshooting=Fehlerbehebungen
tab.extra.options.alwaysontop=Immer im Vordergrund tab.extra.options.alwaysontop=Immer im Vordergrund
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Client-seitige Staff-Berechtigungen tab.extra.options.staffpermissions=Client-seitige Staff-Berechtigungen
tab.extra.options.pythonscripting=G-Python Scripting tab.extra.options.pythonscripting=G-Python Scripting
tab.extra.options.pythonscripting.alert.title=G-Python Installation tab.extra.options.pythonscripting.alert.title=G-Python Installation

View File

@ -94,6 +94,16 @@ tab.extra=Extra
tab.extra.notepad=Notepad tab.extra.notepad=Notepad
tab.extra.troubleshooting=Troubleshooting tab.extra.troubleshooting=Troubleshooting
tab.extra.options.alwaysontop=Always on top tab.extra.options.alwaysontop=Always on top
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Client-side staff permissions tab.extra.options.staffpermissions=Client-side staff permissions
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=G-Python installation tab.extra.options.pythonscripting.alert.title=G-Python installation

View File

@ -95,6 +95,16 @@ tab.extra=Extra
tab.extra.notepad=Notepad tab.extra.notepad=Notepad
tab.extra.troubleshooting=Ayuda tab.extra.troubleshooting=Ayuda
tab.extra.options.alwaysontop=Mostrar siempre arriba tab.extra.options.alwaysontop=Mostrar siempre arriba
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Permisos Staff en cliente tab.extra.options.staffpermissions=Permisos Staff en cliente
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=Instalación de G-Python tab.extra.options.pythonscripting.alert.title=Instalación de G-Python

View File

@ -95,6 +95,16 @@ tab.extra=Lisät
tab.extra.notepad=Muistio tab.extra.notepad=Muistio
tab.extra.troubleshooting=Vianmääritys tab.extra.troubleshooting=Vianmääritys
tab.extra.options.alwaysontop=Aina ylimmäisenä tab.extra.options.alwaysontop=Aina ylimmäisenä
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Client-side staffioikeudet tab.extra.options.staffpermissions=Client-side staffioikeudet
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=G-Python -asennus tab.extra.options.pythonscripting.alert.title=G-Python -asennus

View File

@ -97,6 +97,16 @@ tab.extra=Extra
tab.extra.notepad=Notepad tab.extra.notepad=Notepad
tab.extra.troubleshooting=Dépannage tab.extra.troubleshooting=Dépannage
tab.extra.options.alwaysontop=Toujours au top tab.extra.options.alwaysontop=Toujours au top
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Permission staff client tab.extra.options.staffpermissions=Permission staff client
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=G-Python installation tab.extra.options.pythonscripting.alert.title=G-Python installation

View File

@ -94,6 +94,16 @@ tab.extra=Extra
tab.extra.notepad=Notepad tab.extra.notepad=Notepad
tab.extra.troubleshooting=Risoluzione dei problemi tab.extra.troubleshooting=Risoluzione dei problemi
tab.extra.options.alwaysontop=Sempre in primo piano tab.extra.options.alwaysontop=Sempre in primo piano
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Permessi staff client-side tab.extra.options.staffpermissions=Permessi staff client-side
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=Installazione di G-Python tab.extra.options.pythonscripting.alert.title=Installazione di G-Python

View File

@ -94,6 +94,16 @@ tab.extra=Extra
tab.extra.notepad=Kladblok tab.extra.notepad=Kladblok
tab.extra.troubleshooting=Troubleshooting tab.extra.troubleshooting=Troubleshooting
tab.extra.options.alwaysontop=Altijd bovenop tab.extra.options.alwaysontop=Altijd bovenop
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Client-side staff machtigingen tab.extra.options.staffpermissions=Client-side staff machtigingen
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=G-Python installatie tab.extra.options.pythonscripting.alert.title=G-Python installatie

View File

@ -94,6 +94,16 @@ tab.extra=Extra
tab.extra.notepad=Anotações tab.extra.notepad=Anotações
tab.extra.troubleshooting=Resolução de problemas tab.extra.troubleshooting=Resolução de problemas
tab.extra.options.alwaysontop=Manter no topo tab.extra.options.alwaysontop=Manter no topo
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=Permissões de staff no Cliente tab.extra.options.staffpermissions=Permissões de staff no Cliente
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=Instalação do G-Python tab.extra.options.pythonscripting.alert.title=Instalação do G-Python

View File

@ -95,6 +95,16 @@ tab.extra=Ekstra
tab.extra.notepad=Not dosyası tab.extra.notepad=Not dosyası
tab.extra.troubleshooting=Sorun giderme tab.extra.troubleshooting=Sorun giderme
tab.extra.options.alwaysontop=Her zaman üstte tab.extra.options.alwaysontop=Her zaman üstte
tab.extra.options.developmode=Developer mode
tab.extra.options.developmode.alert.title=About developer mode
tab.extra.options.developmode.alert.content=By enabling developer mode, you can send unsafe packets and install extensions from local files.\n\
Be warned, sending unsafe packets may get you permanently banned if the Habbo servers detect\n\
they have an invalid header ID. If you enabled developer mode to install extensions from\n\
external sources, make sure you trust the creator. A malicious creator could try to hack you!\n\
\n\
All the extensions from the G-ExtensionStore are safe.\n\
\n\
Are you sure you want to continue?
tab.extra.options.staffpermissions=İstemci tarafı personel izinleri tab.extra.options.staffpermissions=İstemci tarafı personel izinleri
tab.extra.options.pythonscripting=G-Python scripting tab.extra.options.pythonscripting=G-Python scripting
tab.extra.options.pythonscripting.alert.title=G-Python Kurulum tab.extra.options.pythonscripting.alert.title=G-Python Kurulum