Add server add, edit and remove

This commit is contained in:
rtm516 2020-06-18 01:04:42 +01:00
parent 93ce059e3e
commit a47b395471
7 changed files with 266 additions and 22 deletions

View file

@ -17,12 +17,13 @@ GeyserConnect is a server that Minecraft: Bedrock Edition clients can connect to
## TODO ## TODO
- [x] Auto start Geyser instance - [x] Auto start Geyser instance
- [x] Transfer player to Geyser instance and connect to correct server - [x] Transfer player to Geyser instance and connect to correct server
- [ ] Server list - [x] Server list
- [x] View - [x] View
- [ ] Add - [x] Add
- [ ] Remove - [x] Remove
- [x] Edit
- [ ] Stop Geyser server after its idle for a while - [ ] Stop Geyser server after its idle for a while
- [x] Config file - [x] Config file
- [x] Fix server images not loading straight away on Win10 - [x] Fix server images not loading straight away on Win10
- [ ] Per server online/offline mode - [ ] Per server online/offline mode (50%)
- [ ] Add option to add a bedrock server - [ ] Add option to add a bedrock server

View file

@ -29,6 +29,7 @@ package org.geysermc.connect;
import com.nukkitx.protocol.bedrock.*; import com.nukkitx.protocol.bedrock.*;
import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
import lombok.Getter; import lombok.Getter;
import org.geysermc.connect.utils.Server;
import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connect.proxy.GeyserProxyBootstrap; import org.geysermc.connect.proxy.GeyserProxyBootstrap;
import org.geysermc.connect.storage.AbstractStorageManager; import org.geysermc.connect.storage.AbstractStorageManager;
@ -155,12 +156,14 @@ public class MasterServer {
public void shutdown() { public void shutdown() {
shuttingDown = true; shuttingDown = true;
generalThreadPool.shutdown();
storageManager.closeStorage();
if (geyserProxy != null) { if (geyserProxy != null) {
geyserProxy.onDisable(); geyserProxy.onDisable();
} }
generalThreadPool.shutdown();
storageManager.closeStorage();
System.exit(0);
} }
public void createGeyserProxy() { public void createGeyserProxy() {

View file

@ -51,6 +51,7 @@ import java.io.IOException;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
public class PacketHandler implements BedrockPacketHandler { public class PacketHandler implements BedrockPacketHandler {
@ -219,6 +220,22 @@ public class PacketHandler implements BedrockPacketHandler {
UIHandler.handleEditServerListResponse(player, (SimpleFormResponse) window.getResponse()); UIHandler.handleEditServerListResponse(player, (SimpleFormResponse) window.getResponse());
break; break;
case ADD_SERVER:
UIHandler.handleAddServerResponse(player, (CustomFormResponse) window.getResponse());
break;
case SERVER_OPTIONS:
UIHandler.handleServerOptionsResponse(player, (SimpleFormResponse) window.getResponse());
break;
case REMOVE_SERVER:
UIHandler.handleServerRemoveResponse(player, (SimpleFormResponse) window.getResponse());
break;
case EDIT_SERVER:
UIHandler.handleEditServerResponse(player, (CustomFormResponse) window.getResponse());
break;
default: default:
player.resendWindow(); player.resendWindow();
break; break;
@ -236,7 +253,9 @@ public class PacketHandler implements BedrockPacketHandler {
List<Attribute> attributes = new ArrayList<>(); List<Attribute> attributes = new ArrayList<>();
attributes.add(AttributeUtils.getBedrockAttribute(AttributeType.EXPERIENCE_LEVEL.getAttribute(0f))); attributes.add(AttributeUtils.getBedrockAttribute(AttributeType.EXPERIENCE_LEVEL.getAttribute(0f)));
updateAttributesPacket.setAttributes(attributes); updateAttributesPacket.setAttributes(attributes);
session.sendPacket(updateAttributesPacket);
// Doesn't work 100% of the time but fixes it most of the time
MasterServer.getInstance().getGeneralThreadPool().schedule(() -> session.sendPacket(updateAttributesPacket), 500, TimeUnit.MILLISECONDS);
return false; return false;
} }

View file

@ -34,8 +34,10 @@ public enum FormID {
MAIN, MAIN,
DIRECT_CONNECT(true), DIRECT_CONNECT(true),
EDIT_SERVERS(true), EDIT_SERVERS(true),
ADD_SERVER, SERVER_OPTIONS(true),
ADD_SERVER(true),
REMOVE_SERVER, REMOVE_SERVER,
EDIT_SERVER(true),
CONNECTING, CONNECTING,
ERROR; ERROR;

View file

@ -33,6 +33,9 @@ import org.geysermc.common.window.SimpleFormWindow;
import org.geysermc.common.window.button.FormButton; import org.geysermc.common.window.button.FormButton;
import org.geysermc.common.window.button.FormImage; import org.geysermc.common.window.button.FormImage;
import org.geysermc.common.window.component.InputComponent; import org.geysermc.common.window.component.InputComponent;
import org.geysermc.common.window.component.LabelComponent;
import org.geysermc.common.window.component.SliderComponent;
import org.geysermc.common.window.component.ToggleComponent;
import org.geysermc.common.window.response.CustomFormResponse; import org.geysermc.common.window.response.CustomFormResponse;
import org.geysermc.common.window.response.SimpleFormResponse; import org.geysermc.common.window.response.SimpleFormResponse;
import org.geysermc.connect.MasterServer; import org.geysermc.connect.MasterServer;
@ -89,12 +92,13 @@ public class UIHandler {
/** /**
* Create a direct connect form * Create a direct connect form
* *
* @return A {@link SimpleFormWindow} object * @return A {@link CustomFormWindow} object
*/ */
public static FormWindow getDirectConnect() { public static FormWindow getDirectConnect() {
CustomFormWindow window = new CustomFormBuilder("Direct Connect") CustomFormWindow window = new CustomFormBuilder("Direct Connect")
.addComponent(new InputComponent("IP", "play.cubecraft.net", "")) .addComponent(new InputComponent("IP", "play.cubecraft.net", ""))
.addComponent(new InputComponent("Port", "25565", "25565")) .addComponent(new InputComponent("Port", "25565", "25565"))
.addComponent(new ToggleComponent("Online mode", true))
.build(); .build();
return window; return window;
} }
@ -113,6 +117,71 @@ public class UIHandler {
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.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.getButtons().add(new FormButton("Add server"));
window.getButtons().add(new FormButton("Back"));
return window;
}
/**
* Create a add server form
*
* @return A {@link CustomFormWindow} object
*/
public static FormWindow getAddServer() {
CustomFormWindow window = new CustomFormBuilder("Add Server")
.addComponent(new InputComponent("IP", "play.cubecraft.net", ""))
.addComponent(new InputComponent("Port", "25565", "25565"))
.addComponent(new ToggleComponent("Online mode", true))
.build();
return window;
}
/**
* Create a server options form
*
* @param server A {@link Server} object to show options for
* @return A {@link SimpleFormWindow} object
*/
public static FormWindow getServerOptions(Server server) {
SimpleFormWindow window = new SimpleFormWindow("Server Options", server.toString());
window.getButtons().add(new FormButton("Edit"));
window.getButtons().add(new FormButton("Remove"));
window.getButtons().add(new FormButton("Back"));
return window;
}
/**
* Create a remove server form
*
* @param server A {@link Server} object to remove
* @return A {@link SimpleFormWindow} 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;
}
/**
* Create a edit server form
*
* @param server A {@link Server} object to edit
* @return A {@link CustomFormWindow} object
*/
public static FormWindow getEditServer(int serverIndex, Server server) {
String port = String.valueOf(server.getPort());
CustomFormWindow window = 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()))
.build();
return window; return window;
} }
@ -151,13 +220,14 @@ public class UIHandler {
public static void handleDirectConnectResponse(Player player, CustomFormResponse data) { public static void handleDirectConnectResponse(Player player, CustomFormResponse data) {
// Take them back to the main menu if they close the direct connect window // Take them back to the main menu if they close the direct connect window
if (data == null) { if (data == null) {
player.sendWindow(FormID.MAIN, getServerList(player.getServers()));; player.sendWindow(FormID.MAIN, getServerList(player.getServers()));
return; return;
} }
try { try {
String address = data.getInputResponses().get(0); String address = data.getInputResponses().get(0);
int port = Integer.valueOf(data.getInputResponses().get(1)); int port = Integer.valueOf(data.getInputResponses().get(1));
boolean online = data.getToggleResponses().get(2);
// Make sure we got an address and port // Make sure we got an address and port
if (address == null || "".equals(address) || port <= 0 || port >= 65535) { if (address == null || "".equals(address) || port <= 0 || port >= 65535) {
@ -165,7 +235,7 @@ public class UIHandler {
return; return;
} }
player.sendToServer(new Server(address, port)); player.sendToServer(new Server(address, port, online));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
player.resendWindow(); player.resendWindow();
} }
@ -180,11 +250,158 @@ public class UIHandler {
public static void handleEditServerListResponse(Player player, SimpleFormResponse data) { public static void handleEditServerListResponse(Player player, SimpleFormResponse data) {
// Take them back to the main menu if they close the edit server list window // Take them back to the main menu if they close the edit server list window
if (data == null) { if (data == null) {
player.sendWindow(FormID.MAIN, getServerList(player.getServers()));; player.sendWindow(FormID.MAIN, getServerList(player.getServers()));
return; return;
} }
// Just redisplay the form for now List<Server> servers = player.getServers();
player.resendWindow(); if (data.getClickedButtonId() == servers.size()) {
player.sendWindow(FormID.ADD_SERVER, getAddServer());
} else if (data.getClickedButtonId() == servers.size() + 1) {
player.sendWindow(FormID.MAIN, getServerList(player.getServers()));
} else {
Server server = player.getServers().get(data.getClickedButtonId());
player.sendWindow(FormID.SERVER_OPTIONS, getServerOptions(server));
}
}
/**
* Handle the add server response
*
* @param player The player that submitted the response
* @param data The form response data
*/
public static void handleAddServerResponse(Player player, CustomFormResponse data) {
// Take them back to the edit server list menu if they close the add server window
if (data == null) {
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
return;
}
try {
String address = data.getInputResponses().get(0);
int port = Integer.valueOf(data.getInputResponses().get(1));
boolean online = data.getToggleResponses().get(2);
// Make sure we got an address and port
if (address == null || "".equals(address) || port <= 0 || port >= 65535) {
player.resendWindow();
return;
}
player.getServers().add(new Server(address, port, online));
// Send them back to the edit screen
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
} catch (NumberFormatException e) {
player.resendWindow();
}
}
/**
* Handle the server options response
*
* @param player The player that submitted the response
* @param data The form response data
*/
public static void handleServerOptionsResponse(Player player, SimpleFormResponse data) {
// Take them back to the main menu if they close the edit server list window
if (data == null) {
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
return;
}
SimpleFormWindow window = (SimpleFormWindow) player.getCurrentWindow();
Server selectedServer = null;
for (Server server : player.getServers()) {
if (server.toString().equals(window.getContent())) {
selectedServer = server;
break;
}
}
if (selectedServer == null) {
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
return;
}
switch (data.getClickedButtonId()) {
case 0:
player.sendWindow(FormID.EDIT_SERVER, getEditServer(player.getServers().indexOf(selectedServer), selectedServer));
break;
case 1:
player.sendWindow(FormID.REMOVE_SERVER, getRemoveServer(selectedServer));
break;
default:
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
break;
}
}
/**
* Handle the server remove response
*
* @param player The player that submitted the response
* @param data The form response data
*/
public static void handleServerRemoveResponse(Player player, SimpleFormResponse data) {
SimpleFormWindow window = (SimpleFormWindow) player.getCurrentWindow();
String serverName = window.getContent().split(":")[1].trim();
Server selectedServer = null;
for (Server server : player.getServers()) {
if (server.toString().equals(serverName)) {
selectedServer = server;
break;
}
}
if (selectedServer == null) {
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
return;
}
if (data.getClickedButtonId() == 0) {
player.getServers().remove(selectedServer);
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
} else {
player.sendWindow(FormID.SERVER_OPTIONS, getServerOptions(selectedServer));
}
}
/**
* Handle the edit server response
*
* @param player The player that submitted the response
* @param data The form response data
*/
public static void handleEditServerResponse(Player player, CustomFormResponse data) {
// Take them back to the edit server list menu if they close the add server window
if (data == null) {
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
return;
}
try {
int serverIndex = Integer.valueOf(data.getLabelResponses().get(0).split(":")[1].trim());
String address = data.getInputResponses().get(1);
int port = Integer.valueOf(data.getInputResponses().get(2));
boolean online = data.getToggleResponses().get(3);
// Make sure we got an address and port
if (address == null || "".equals(address) || port <= 0 || port >= 65535) {
player.resendWindow();
return;
}
player.getServers().set(serverIndex, new Server(address, port, online));
// Send them back to the edit screen
player.sendWindow(FormID.EDIT_SERVERS, getEditServerList(player.getServers()));
} catch (NumberFormatException e) {
player.resendWindow();
}
} }
} }

View file

@ -51,7 +51,7 @@ public class PalleteManger {
static { static {
/* Load block palette */ /* Load block palette */
InputStream stream = FileUtils.getResource("runtime_block_states.dat"); InputStream stream = FileUtils.getResource("bedrock/runtime_block_states.dat");
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) { try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) {
BLOCK_PALLETE = (ListTag<CompoundTag>) nbtInputStream.readTag(); BLOCK_PALLETE = (ListTag<CompoundTag>) nbtInputStream.readTag();
@ -60,7 +60,7 @@ public class PalleteManger {
} }
/* Load biomes */ /* Load biomes */
stream = FileUtils.getResource("biome_definitions.dat"); stream = FileUtils.getResource("bedrock/biome_definitions.dat");
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)){ try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)){
BIOMES_PALLETE = (CompoundTag) nbtInputStream.readTag(); BIOMES_PALLETE = (CompoundTag) nbtInputStream.readTag();

View file

@ -28,21 +28,23 @@ package org.geysermc.connect.utils;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor
public class Server { public class Server {
private String address; private String address;
private int port = 25565; private int port = 25565;
private boolean online = true;
// Added so we can load from config
public Server() {
super();
}
public Server(String address) { public Server(String address) {
this(address, 25565); this(address, 25565, true);
}
public Server(String address, int port) {
this(address, port, true);
} }
@Override @Override