diff --git a/bind9/db.play.pixelparadise.gg b/bind9/db.play.pixelparadise.gg new file mode 100644 index 0000000..2a3cc48 --- /dev/null +++ b/bind9/db.play.pixelparadise.gg @@ -0,0 +1,11 @@ +@ in SOA play.pixelparadise.gg. admin.play.pixelparadise.gg. ( + 2014030801 ; serial + 1D ; refresh + 1H ; retry + 1W ; expire + 3H ) ; minimum + +@ NS play.pixelparadise.gg. + + IN A 167.71.133.54 + IN AAAA 2a03:b0c0:1:e0::6a5:b001 \ No newline at end of file diff --git a/bind9/named.conf.local b/bind9/named.conf.local index 8b9bb08..3660158 100644 --- a/bind9/named.conf.local +++ b/bind9/named.conf.local @@ -41,3 +41,9 @@ zone "play.galaxite.net" IN { file "/etc/bind/db.play.galaxite.net"; allow-query { any; }; }; + +zone "play.pixelparadise.gg" IN { + type master; + file "/etc/bind/db.play.pixelparadise.gg"; + allow-query { any; }; +}; diff --git a/pom.xml b/pom.xml index 71ba4ae..f990e6e 100644 --- a/pom.xml +++ b/pom.xml @@ -62,18 +62,18 @@ org.projectlombok lombok - 1.18.4 + 1.18.20 provided org.geysermc connector - 1.2.1-SNAPSHOT + 1.4.0-SNAPSHOT com.github.CloudburstMC.Protocol - bedrock-v431 - f8ecf54 + bedrock-v440 + 1656151 compile diff --git a/src/main/java/org/geysermc/connect/PacketHandler.java b/src/main/java/org/geysermc/connect/PacketHandler.java index bd4864e..237bb69 100644 --- a/src/main/java/org/geysermc/connect/PacketHandler.java +++ b/src/main/java/org/geysermc/connect/PacketHandler.java @@ -38,24 +38,27 @@ import com.nukkitx.protocol.bedrock.data.AttributeData; import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler; import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.util.EncryptionUtils; -import org.geysermc.common.window.FormWindow; -import org.geysermc.common.window.response.CustomFormResponse; -import org.geysermc.common.window.response.SimpleFormResponse; import org.geysermc.connect.ui.FormID; import org.geysermc.connect.ui.UIHandler; import org.geysermc.connect.utils.Player; import org.geysermc.connect.utils.Server; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.network.BedrockProtocol; +import org.geysermc.connector.network.session.auth.AuthData; import org.geysermc.connector.network.session.auth.BedrockClientData; import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.FileUtils; +import org.geysermc.cumulus.Form; +import org.geysermc.cumulus.response.CustomFormResponse; +import org.geysermc.cumulus.response.FormResponse; +import org.geysermc.cumulus.response.SimpleFormResponse; import java.io.File; import java.io.IOException; import java.security.interfaces.ECPublicKey; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.concurrent.TimeUnit; public class PacketHandler implements BedrockPacketHandler { @@ -153,8 +156,15 @@ public class PacketHandler implements BedrockPacketHandler { // Fetch the client data JsonNode extraData = payload.get("extraData"); + AuthData authData = new AuthData( + extraData.get("displayName").asText(), + UUID.fromString(extraData.get("identity").asText()), + extraData.get("XUID").asText(), + chainData, packet.getSkinData().toString() + ); + // Create a new player and add it to the players list - player = new Player(extraData, session); + player = new Player(authData, session); masterServer.getPlayers().put(player.getAuthData().getXboxUUID(), player); // Store the full client data @@ -267,11 +277,11 @@ public class PacketHandler implements BedrockPacketHandler { return false; // Fetch the form and parse the response - FormWindow window = player.getCurrentWindow(); - window.setResponse(packet.getFormData().trim()); + Form window = player.getCurrentWindow(); + FormResponse response = window.parseResponse(packet.getFormData().trim()); // Resend the form if they closed it - if (window.getResponse() == null && !id.isHandlesNull()) { + if (!response.isCorrect() && !id.isHandlesNull()) { player.resendWindow(); } else { // Send the response to the correct response function @@ -281,35 +291,35 @@ public class PacketHandler implements BedrockPacketHandler { break; case MAIN: - UIHandler.handleMainMenuResponse(player, (SimpleFormResponse) window.getResponse()); + UIHandler.handleMainMenuResponse(player, (SimpleFormResponse) response); break; case LIST_SERVERS: - UIHandler.handleServerListResponse(player, (SimpleFormResponse) window.getResponse()); + UIHandler.handleServerListResponse(player, (SimpleFormResponse) response); break; case DIRECT_CONNECT: - UIHandler.handleDirectConnectResponse(player, (CustomFormResponse) window.getResponse()); + UIHandler.handleDirectConnectResponse(player, (CustomFormResponse) response); break; case EDIT_SERVERS: - UIHandler.handleEditServerListResponse(player, (SimpleFormResponse) window.getResponse()); + UIHandler.handleEditServerListResponse(player, (SimpleFormResponse) response); break; case ADD_SERVER: - UIHandler.handleAddServerResponse(player, (CustomFormResponse) window.getResponse()); + UIHandler.handleAddServerResponse(player, (CustomFormResponse) response); break; case SERVER_OPTIONS: - UIHandler.handleServerOptionsResponse(player, (SimpleFormResponse) window.getResponse()); + UIHandler.handleServerOptionsResponse(player, (SimpleFormResponse) response); break; case REMOVE_SERVER: - UIHandler.handleServerRemoveResponse(player, (SimpleFormResponse) window.getResponse()); + UIHandler.handleServerRemoveResponse(player, (SimpleFormResponse) response); break; case EDIT_SERVER: - UIHandler.handleEditServerResponse(player, (CustomFormResponse) window.getResponse()); + UIHandler.handleEditServerResponse(player, (CustomFormResponse) response); break; default: diff --git a/src/main/java/org/geysermc/connect/ui/UIHandler.java b/src/main/java/org/geysermc/connect/ui/UIHandler.java index a97f12b..0533b61 100644 --- a/src/main/java/org/geysermc/connect/ui/UIHandler.java +++ b/src/main/java/org/geysermc/connect/ui/UIHandler.java @@ -25,21 +25,19 @@ package org.geysermc.connect.ui; -import org.geysermc.common.window.CustomFormBuilder; -import org.geysermc.common.window.CustomFormWindow; -import org.geysermc.common.window.FormWindow; -import org.geysermc.common.window.SimpleFormWindow; -import org.geysermc.common.window.button.FormButton; -import org.geysermc.common.window.button.FormImage; -import org.geysermc.common.window.component.InputComponent; -import org.geysermc.common.window.component.LabelComponent; -import org.geysermc.common.window.component.ToggleComponent; -import org.geysermc.common.window.response.CustomFormResponse; -import org.geysermc.common.window.response.SimpleFormResponse; import org.geysermc.connect.MasterServer; import org.geysermc.connect.utils.Player; import org.geysermc.connect.utils.Server; import org.geysermc.connect.utils.ServerCategory; +import org.geysermc.cumulus.CustomForm; +import org.geysermc.cumulus.Form; +import org.geysermc.cumulus.SimpleForm; +import org.geysermc.cumulus.component.InputComponent; +import org.geysermc.cumulus.component.LabelComponent; +import org.geysermc.cumulus.component.ToggleComponent; +import org.geysermc.cumulus.response.CustomFormResponse; +import org.geysermc.cumulus.response.SimpleFormResponse; +import org.geysermc.cumulus.util.FormImage; import java.util.List; @@ -48,23 +46,23 @@ public class UIHandler { /** * Create a list of servers for the client based on the passed servers list * - * @return A {@link SimpleFormWindow} object + * @return A {@link SimpleForm} object */ - public static FormWindow getMainMenu() { - SimpleFormWindow window = new SimpleFormWindow("Main Menu", ""); + public static Form getMainMenu() { + SimpleForm.Builder window = SimpleForm.builder().title("Main Menu"); - window.getButtons().add(new FormButton("Official Servers")); - window.getButtons().add(new FormButton("Geyser Servers")); + window.button("Official Servers"); + window.button("Geyser Servers"); // Add a buttons for custom servers if (MasterServer.getInstance().getGeyserConnectConfig().getCustomServers().isEnabled()) { - window.getButtons().add(new FormButton("Custom Servers")); - window.getButtons().add(new FormButton("Direct connect")); + window.button("Custom Servers"); + window.button("Direct connect"); } - window.getButtons().add(new FormButton("Disconnect")); + window.button("Disconnect"); - return window; + return window.build(); } /** @@ -72,49 +70,49 @@ public class UIHandler { * * @param servers A list of {@link Server} objects * @param category The category of the current list - * @return A {@link SimpleFormWindow} object + * @return A {@link SimpleForm} object */ - public static FormWindow getServerList(List servers, ServerCategory category) { - SimpleFormWindow window = new SimpleFormWindow(category.getTitle() + " Servers", ""); + public static Form getServerList(List servers, ServerCategory category) { + SimpleForm.Builder window = SimpleForm.builder().title(category.getTitle() + " Servers"); // Add a button for each global server for (Server server : servers) { // These images would be better if there was a default to fall back on // But that would require a web api as bedrock doesn't support doing that - window.getButtons().add(new FormButton(server.toString(), server.getFormImage())); + window.button(server.toString(), server.getFormImage()); } // Add a button for editing if (category == ServerCategory.CUSTOM) { - window.getButtons().add(new FormButton("Edit servers")); + window.button("Edit servers"); } - window.getButtons().add(new FormButton("Back")); + window.button("Back"); - return window; + return window.build(); } /** * Create a simple connecting message form * * @param server The server info to display - * @return A {@link SimpleFormWindow} object + * @return A {@link SimpleForm} object */ - public static FormWindow getWaitingScreen(Server server) { - return new SimpleFormWindow("Connecting", "Please wait while we connect you to " + server.toString()); + public static Form getWaitingScreen(Server server) { + return SimpleForm.builder().title("Connecting").content("Please wait while we connect you to " + server.toString()).build(); } /** * Create a direct connect form * - * @return A {@link CustomFormWindow} object + * @return A {@link CustomForm} object */ - public static FormWindow getDirectConnect() { - return new CustomFormBuilder("Direct Connect") - .addComponent(new InputComponent("IP", "play.cubecraft.net", "")) - .addComponent(new InputComponent("Port", "25565", "25565")) - .addComponent(new ToggleComponent("Online mode", true)) - .addComponent(new ToggleComponent("Bedrock/Geyser server", false)) + public static Form getDirectConnect() { + return CustomForm.builder().title("Direct Connect") + .component(InputComponent.of("IP", "play.cubecraft.net")) + .component(InputComponent.of("Port", "25565", "25565")) + .component(ToggleComponent.of("Online mode", true)) + .component(ToggleComponent.of("Bedrock/Geyser server", false)) .build(); } @@ -122,33 +120,34 @@ public class UIHandler { * Create a list of servers for the client to edit * * @param servers A list of {@link Server} objects - * @return A {@link SimpleFormWindow} object + * @return A {@link SimpleForm} object */ - public static FormWindow getEditServerList(List servers) { - SimpleFormWindow window = new SimpleFormWindow("Edit Servers", "Select a server to edit"); + public static Form getEditServerList(List servers) { + SimpleForm.Builder window = SimpleForm.builder().title("Edit Servers").content("Select a server to edit"); // Add a button for each personal server for (Server server : servers) { - window.getButtons().add(new FormButton(server.toString(), new FormImage(FormImage.FormImageType.URL, "https://eu.mc-api.net/v3/server/favicon/" + server.getAddress() + ":" + server.getPort() + ".png"))); + window.button(server.toString(), FormImage.of(FormImage.Type.URL, + "https://eu.mc-api.net/v3/server/favicon/" + server.getAddress() + ":" + server.getPort() + ".png")); } - window.getButtons().add(new FormButton("Add server")); - window.getButtons().add(new FormButton("Back")); + window.button("Add server"); + window.button("Back"); - return window; + return window.build(); } /** * Create a add server form * - * @return A {@link CustomFormWindow} object + * @return A {@link CustomForm} object */ - public static FormWindow getAddServer() { - return new CustomFormBuilder("Add Server") - .addComponent(new InputComponent("IP", "play.cubecraft.net", "")) - .addComponent(new InputComponent("Port", "25565", "25565")) - .addComponent(new ToggleComponent("Online mode", true)) - .addComponent(new ToggleComponent("Bedrock server", false)) + public static Form getAddServer() { + return CustomForm.builder().title("Add Server") + .component(InputComponent.of("IP", "play.cubecraft.net")) + .component(InputComponent.of("Port", "25565", "25565")) + .component(ToggleComponent.of("Online mode", true)) + .component(ToggleComponent.of("Bedrock/Geyser server", false)) .build(); } @@ -156,47 +155,47 @@ public class UIHandler { * Create a server options form * * @param server A {@link Server} object to show options for - * @return A {@link SimpleFormWindow} object + * @return A {@link SimpleForm} object */ - public static FormWindow getServerOptions(Server server) { - SimpleFormWindow window = new SimpleFormWindow("Server Options", server.toString()); + public static Form getServerOptions(Server server) { + SimpleForm.Builder window = SimpleForm.builder().title("Server Options").content(server.toString()); - window.getButtons().add(new FormButton("Edit")); - window.getButtons().add(new FormButton("Remove")); - window.getButtons().add(new FormButton("Back")); + window.button("Edit"); + window.button("Remove"); + window.button("Back"); - return window; + return window.build(); } /** * Create a remove server form * * @param server A {@link Server} object to remove - * @return A {@link SimpleFormWindow} object + * @return A {@link SimpleForm} object */ - public static FormWindow getRemoveServer(Server server) { - SimpleFormWindow window = new SimpleFormWindow("Remove Server", "Are you sure you want to remove server: " + server.toString()); - - window.getButtons().add(new FormButton("Remove")); - window.getButtons().add(new FormButton("Cancel")); - - return window; + public static Form getRemoveServer(Server server) { + return SimpleForm.builder() + .title("Remove Server") + .content("Are you sure you want to remove server: " + server) + .button("Remove") + .button("Cancel") + .build(); } /** * Create a edit server form * * @param server A {@link Server} object to edit - * @return A {@link CustomFormWindow} object + * @return A {@link CustomForm} object */ - public static FormWindow getEditServer(int serverIndex, Server server) { + public static Form getEditServer(int serverIndex, Server server) { String port = String.valueOf(server.getPort()); - return new CustomFormBuilder("Edit Server") - .addComponent(new LabelComponent("Server at index: " + serverIndex)) - .addComponent(new InputComponent("IP", server.getAddress(), server.getAddress())) - .addComponent(new InputComponent("Port", port, port)) - .addComponent(new ToggleComponent("Online mode", server.isOnline())) - .addComponent(new ToggleComponent("Bedrock server", server.isBedrock())) + return CustomForm.builder() + .component(LabelComponent.of("Server at index: " + serverIndex)) + .component(InputComponent.of("IP", server.getAddress(), server.getAddress())) + .component(InputComponent.of("Port", port, port)) + .component(ToggleComponent.of("Online mode", server.isOnline())) + .component(ToggleComponent.of("Bedrock/Geyser server", server.isBedrock())) .build(); } @@ -204,11 +203,12 @@ public class UIHandler { * Show a basic form window with a message * * @param message The message to display - * @return A {@link CustomFormWindow} object + * @return A {@link CustomForm} object */ - public static FormWindow getMessageWindow(String message) { - return new CustomFormBuilder("Notice") - .addComponent(new LabelComponent(message)) + public static Form getMessageWindow(String message) { + return CustomForm.builder() + .title("Notice") + .component(LabelComponent.of(message)) .build(); } @@ -300,10 +300,10 @@ public class UIHandler { } try { - String address = data.getInputResponses().get(0); - int port = Integer.parseInt(data.getInputResponses().get(1)); - boolean online = data.getToggleResponses().get(2); - boolean bedrock = data.getToggleResponses().get(3); + String address = data.getInput(0); + int port = Integer.parseInt(data.getInput(1)); + boolean online = data.getToggle(2); + boolean bedrock = data.getToggle(3); // Make sure we got an address if (address == null || "".equals(address)) { @@ -362,10 +362,10 @@ public class UIHandler { } try { - String address = data.getInputResponses().get(0); - int port = Integer.parseInt(data.getInputResponses().get(1)); - boolean online = data.getToggleResponses().get(2); - boolean bedrock = data.getToggleResponses().get(3); + String address = data.getInput(0); + int port = Integer.parseInt(data.getInput(1)); + boolean online = data.getToggle(2); + boolean bedrock = data.getToggle(3); // Make sure we got an address if (address == null || "".equals(address)) { @@ -401,7 +401,7 @@ public class UIHandler { return; } - SimpleFormWindow window = (SimpleFormWindow) player.getCurrentWindow(); + SimpleForm window = (SimpleForm) player.getCurrentWindow(); Server selectedServer = null; for (Server server : player.getServers()) { if (server.toString().equals(window.getContent())) { @@ -437,7 +437,7 @@ public class UIHandler { * @param data The form response data */ public static void handleServerRemoveResponse(Player player, SimpleFormResponse data) { - SimpleFormWindow window = (SimpleFormWindow) player.getCurrentWindow(); + SimpleForm window = (SimpleForm) player.getCurrentWindow(); String serverName = window.getContent().split(":")[1].trim(); Server selectedServer = null; for (Server server : player.getServers()) { @@ -474,12 +474,12 @@ public class UIHandler { } try { - int serverIndex = Integer.parseInt(data.getLabelResponses().get(0).split(":")[1].trim()); + int serverIndex = Integer.parseInt(data.getInput(0).split(":")[1].trim()); - String address = data.getInputResponses().get(1); - int port = Integer.parseInt(data.getInputResponses().get(2)); - boolean online = data.getToggleResponses().get(3); - boolean bedrock = data.getToggleResponses().get(4); + String address = data.getInput(1); + int port = Integer.parseInt(data.getInput(2)); + boolean online = data.getToggle(3); + boolean bedrock = data.getToggle(4); // Make sure we got an address if (address == null || "".equals(address)) { diff --git a/src/main/java/org/geysermc/connect/utils/Player.java b/src/main/java/org/geysermc/connect/utils/Player.java index 92a10eb..5531d36 100644 --- a/src/main/java/org/geysermc/connect/utils/Player.java +++ b/src/main/java/org/geysermc/connect/utils/Player.java @@ -25,19 +25,16 @@ package org.geysermc.connect.utils; -import com.fasterxml.jackson.databind.JsonNode; import com.nukkitx.math.vector.Vector2f; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.packet.*; -import com.nukkitx.protocol.bedrock.v428.Bedrock_v428; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; -import org.geysermc.common.window.FormWindow; import org.geysermc.connect.MasterServer; import org.geysermc.connect.proxy.GeyserProxySession; import org.geysermc.connect.ui.FormID; @@ -50,14 +47,12 @@ import org.geysermc.connector.network.session.auth.BedrockClientData; import org.geysermc.connector.network.translators.BiomeTranslator; import org.geysermc.connector.network.translators.EntityIdentifierRegistry; import org.geysermc.connector.network.translators.item.ItemRegistry; -import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_100; -import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210; -import org.geysermc.connector.utils.ChunkUtils; +import org.geysermc.connector.network.translators.world.block.BlockTranslator1_17_0; import org.geysermc.connector.utils.DimensionUtils; +import org.geysermc.cumulus.Form; import java.util.ArrayList; import java.util.List; -import java.util.UUID; @Getter public class Player { @@ -69,7 +64,7 @@ public class Player { private final List servers = new ArrayList<>(); private final Long2ObjectMap forms = new Long2ObjectOpenHashMap<>(); - private FormWindow currentWindow; + private Form currentWindow; private FormID currentWindowId; @Setter @@ -81,13 +76,8 @@ public class Player { @Setter private ServerCategory serverCategory; - public Player(JsonNode extraData, BedrockServerSession session) { - this.authData = new AuthData( - extraData.get("displayName").asText(), - UUID.fromString(extraData.get("identity").asText()), - extraData.get("XUID").asText() - ); - + public Player(AuthData authData, BedrockServerSession session) { + this.authData = authData; this.session = session; // Should fetch the servers from some form of db @@ -145,6 +135,7 @@ public class Player { startGamePacket.setCurrentTick(0); startGamePacket.setEnchantmentSeed(0); startGamePacket.setMultiplayerCorrelationId(""); + startGamePacket.setServerEngine(""); SyncedPlayerMovementSettings settings = new SyncedPlayerMovementSettings(); settings.setMovementMode(AuthoritativeMovementMode.CLIENT); @@ -195,15 +186,15 @@ public class Player { * Also cache it against the player for later use * * @param id The {@link FormID} to use for the form - * @param window The {@link FormWindow} to turn into json and send + * @param window The {@link Form} to turn into json and send */ - public void sendWindow(FormID id, FormWindow window) { + public void sendWindow(FormID id, Form window) { this.currentWindow = window; this.currentWindowId = id; ModalFormRequestPacket modalFormRequestPacket = new ModalFormRequestPacket(); modalFormRequestPacket.setFormId(id.ordinal()); - modalFormRequestPacket.setFormData(window.getJSONData()); + modalFormRequestPacket.setFormData(window.getJsonData()); session.sendPacket(modalFormRequestPacket); // This packet is used to fix the image loading bug @@ -233,8 +224,7 @@ public class Player { geyserSession.getUpstream().getSession().setPacketCodec(session.getPacketCodec()); // Set the block translation based off of version - geyserSession.setBlockTranslator(session.getPacketCodec().getProtocolVersion() >= Bedrock_v428.V428_CODEC.getProtocolVersion() - ? BlockTranslator1_16_210.INSTANCE : BlockTranslator1_16_100.INSTANCE); + geyserSession.setBlockTranslator(BlockTranslator1_17_0.INSTANCE); geyserSession.setAuthData(authData); geyserSession.setClientData(clientData); diff --git a/src/main/java/org/geysermc/connect/utils/Server.java b/src/main/java/org/geysermc/connect/utils/Server.java index b3ef37c..a7da7a2 100644 --- a/src/main/java/org/geysermc/connect/utils/Server.java +++ b/src/main/java/org/geysermc/connect/utils/Server.java @@ -29,7 +29,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import org.geysermc.common.window.button.FormImage; +import org.geysermc.cumulus.util.FormImage; @Getter @AllArgsConstructor @@ -80,9 +80,9 @@ public class Server { @JsonIgnore public FormImage getFormImage() { if (imageUrl != null && !imageUrl.isEmpty()) { - return new FormImage(FormImage.FormImageType.URL, imageUrl); + return FormImage.of(FormImage.Type.URL, imageUrl); } else { - return new FormImage(FormImage.FormImageType.URL, "https://eu.mc-api.net/v3/server/favicon/" + address + ":" + port + ".png?use-fallback-icon=true"); + return FormImage.of(FormImage.Type.URL, "https://eu.mc-api.net/v3/server/favicon/" + address + ":" + port + ".png?use-fallback-icon=true"); } } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 180925e..8d5c461 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -75,6 +75,13 @@ servers: category: OFFICIAL imageUrl: 'https://pbs.twimg.com/profile_images/1332400307050045441/MHQvGEUP_400x400.jpg' + - name: Pixel Paradise + address: 40.87.84.59 + port: 19132 + bedrock: true + category: OFFICIAL + imageUrl: 'https://xforgeassets001.xboxlive.com/pf-title-b63a0803d3653643-20ca2/fa7681c4-673d-40e4-9b6a-61d5d0f93d14/PixelParadise.jpg' + - name: Official Geyser Test Server address: test.geysermc.org port: 19132