mirror of
https://github.com/GeyserMC/GeyserConnect.git
synced 2025-06-26 14:15:22 +02:00
Rework how connections work to remove the use for the transfer packets and multiple ports (#30)
* Move to a more linear connection flow and remove the need for a second port * Update configs * Remove un-used remote address config options * Update docker file * Start internal Geyser on boot * Fix srv resolving * Fix inventory data when loading into the server
This commit is contained in:
parent
9bd9c5e176
commit
eeadde0550
17 changed files with 178 additions and 278 deletions
|
@ -5,7 +5,7 @@
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](https://ci.nukkitx.com/job/GeyserMC/job/GeyserConnect/job/master/)
|
[](https://ci.nukkitx.com/job/GeyserMC/job/GeyserConnect/job/master/)
|
||||||
[](http://discord.geysermc.org/)
|
[](http://discord.geysermc.org/)
|
||||||
[](http://hits.dwyl.io/GeyserMC/GeyserConnect)
|
[](http://hits.dwyl.io/GeyserMC/GeyserConnect)
|
||||||
|
|
||||||
GeyserConnect is an easy way for Bedrock Edition clients to connect to any Java Edition servers without having to run anything.
|
GeyserConnect is an easy way for Bedrock Edition clients to connect to any Java Edition servers without having to run anything.
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,4 @@ FROM openjdk:8-jre-slim
|
||||||
RUN mkdir /gsc
|
RUN mkdir /gsc
|
||||||
WORKDIR /gsc
|
WORKDIR /gsc
|
||||||
EXPOSE 19132/udp
|
EXPOSE 19132/udp
|
||||||
EXPOSE 19133/udp
|
|
||||||
CMD ["java", "-Xms1G", "-jar", "GeyserConnect.jar"]
|
CMD ["java", "-Xms1G", "-jar", "GeyserConnect.jar"]
|
|
@ -6,5 +6,5 @@ This contains the docker image and a basic way of running GeyserConnect
|
||||||
2. Build the docker file using `docker build -t geyser-connect .`
|
2. Build the docker file using `docker build -t geyser-connect .`
|
||||||
3. Start geyser using this:
|
3. Start geyser using this:
|
||||||
```
|
```
|
||||||
docker run --name "geyser-c" -d --restart always -p 19132:19132/udp -p 19133:19133/udp -v $(pwd)/data:/gsc geyser-connect
|
docker run --name "geyser-c" -d --restart always -p 19132:19132/udp -v $(pwd)/data:/gsc geyser-connect
|
||||||
```
|
```
|
|
@ -42,9 +42,6 @@ public class GeyserConnectConfig {
|
||||||
|
|
||||||
private String address;
|
private String address;
|
||||||
|
|
||||||
@JsonProperty("remote-address")
|
|
||||||
private String remoteAddress;
|
|
||||||
|
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
@JsonProperty("max-players")
|
@JsonProperty("max-players")
|
||||||
|
@ -69,29 +66,14 @@ public class GeyserConnectConfig {
|
||||||
|
|
||||||
private VirtualHostSection vhost;
|
private VirtualHostSection vhost;
|
||||||
|
|
||||||
public void checkRemoteIP() {
|
|
||||||
if ("auto".equals(remoteAddress)) {
|
|
||||||
remoteAddress = WebUtils.getBody("https://icanhazip.com/").trim();
|
|
||||||
MasterServer.getInstance().getLogger().debug("Auto set remote IP to: " + remoteAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class GeyserConfigSection {
|
public static class GeyserConfigSection {
|
||||||
|
|
||||||
private int port;
|
|
||||||
|
|
||||||
@JsonProperty("cache-chunks")
|
|
||||||
private boolean cacheChunks = true;
|
|
||||||
|
|
||||||
@JsonProperty("allow-password-authentication")
|
@JsonProperty("allow-password-authentication")
|
||||||
private boolean allowPasswordAuthentication = false;
|
private boolean allowPasswordAuthentication = false;
|
||||||
|
|
||||||
@JsonProperty("debug-mode")
|
@JsonProperty("debug-mode")
|
||||||
private boolean debugMode;
|
private boolean debugMode;
|
||||||
|
|
||||||
@JsonProperty("shutdown-time")
|
|
||||||
private int shutdownTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
|
@ -105,8 +105,6 @@ public class MasterServer {
|
||||||
|
|
||||||
logger.setDebug(geyserConnectConfig.isDebugMode());
|
logger.setDebug(geyserConnectConfig.isDebugMode());
|
||||||
|
|
||||||
geyserConnectConfig.checkRemoteIP();
|
|
||||||
|
|
||||||
this.generalThreadPool = Executors.newScheduledThreadPool(32);
|
this.generalThreadPool = Executors.newScheduledThreadPool(32);
|
||||||
|
|
||||||
// Start a timer to keep the thread running
|
// Start a timer to keep the thread running
|
||||||
|
@ -131,7 +129,7 @@ public class MasterServer {
|
||||||
|
|
||||||
// Create the base welcome.txt file
|
// Create the base welcome.txt file
|
||||||
try {
|
try {
|
||||||
FileUtils.fileOrCopiedFromResource(new File(MasterServer.getInstance().getGeyserConnectConfig().getWelcomeFile()), "welcome.txt", (x) -> x);
|
FileUtils.fileOrCopiedFromResource(new File(getGeyserConnectConfig().getWelcomeFile()), "welcome.txt", (x) -> x);
|
||||||
} catch (IOException ignored) { }
|
} catch (IOException ignored) { }
|
||||||
|
|
||||||
start(geyserConnectConfig.getPort());
|
start(geyserConnectConfig.getPort());
|
||||||
|
@ -184,6 +182,10 @@ public class MasterServer {
|
||||||
|
|
||||||
// Start server up
|
// Start server up
|
||||||
bdServer.bind().join();
|
bdServer.bind().join();
|
||||||
|
|
||||||
|
// Create the Geyser instance
|
||||||
|
createGeyserProxy();
|
||||||
|
|
||||||
logger.info("Server started on " + geyserConnectConfig.getAddress() + ":" + port);
|
logger.info("Server started on " + geyserConnectConfig.getAddress() + ":" + port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +202,9 @@ public class MasterServer {
|
||||||
|
|
||||||
public void createGeyserProxy() {
|
public void createGeyserProxy() {
|
||||||
if (geyserProxy == null) {
|
if (geyserProxy == null) {
|
||||||
|
// Make sure Geyser doesn't start the listener
|
||||||
|
GeyserConnector.setShouldStartListener(false);
|
||||||
|
|
||||||
this.geyserProxy = new GeyserProxyBootstrap();
|
this.geyserProxy = new GeyserProxyBootstrap();
|
||||||
geyserProxy.onEnable();
|
geyserProxy.onEnable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.geysermc.connect.utils.Player;
|
||||||
import org.geysermc.connect.utils.Server;
|
import org.geysermc.connect.utils.Server;
|
||||||
import org.geysermc.connector.entity.attribute.AttributeType;
|
import org.geysermc.connector.entity.attribute.AttributeType;
|
||||||
import org.geysermc.connector.network.BedrockProtocol;
|
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.network.session.auth.BedrockClientData;
|
||||||
import org.geysermc.connector.utils.AttributeUtils;
|
import org.geysermc.connector.utils.AttributeUtils;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
@ -57,6 +58,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.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class PacketHandler implements BedrockPacketHandler {
|
public class PacketHandler implements BedrockPacketHandler {
|
||||||
|
@ -77,13 +79,13 @@ public class PacketHandler implements BedrockPacketHandler {
|
||||||
|
|
||||||
public void disconnect(DisconnectReason reason) {
|
public void disconnect(DisconnectReason reason) {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
masterServer.getLogger().info(player.getDisplayName() + " has disconnected from the master server (" + reason + ")");
|
masterServer.getLogger().info(player.getAuthData().getName() + " has disconnected from the master server (" + reason + ")");
|
||||||
masterServer.getStorageManager().saveServers(player);
|
masterServer.getStorageManager().saveServers(player);
|
||||||
|
|
||||||
if (player.getCurrentServer() != null && !player.getCurrentServer().isBedrock()) {
|
if (player.getCurrentServer() != null && !player.getCurrentServer().isBedrock()) {
|
||||||
masterServer.getTransferringPlayers().put(player.getXuid(), player);
|
masterServer.getTransferringPlayers().put(player.getAuthData().getXboxUUID(), player);
|
||||||
}
|
}
|
||||||
masterServer.getPlayers().remove(player.getXuid(), player);
|
masterServer.getPlayers().remove(player.getAuthData().getXboxUUID(), player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,9 +156,16 @@ public class PacketHandler implements BedrockPacketHandler {
|
||||||
// Fetch the client data
|
// Fetch the client data
|
||||||
JsonNode extraData = payload.get("extraData");
|
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
|
// 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.getXuid(), player);
|
masterServer.getPlayers().put(player.getAuthData().getXboxUUID(), player);
|
||||||
|
|
||||||
// Store the full client data
|
// Store the full client data
|
||||||
player.setClientData(OBJECT_MAPPER.convertValue(OBJECT_MAPPER.readTree(skinData.getPayload().toBytes()), BedrockClientData.class));
|
player.setClientData(OBJECT_MAPPER.convertValue(OBJECT_MAPPER.readTree(skinData.getPayload().toBytes()), BedrockClientData.class));
|
||||||
|
@ -185,7 +194,7 @@ public class PacketHandler implements BedrockPacketHandler {
|
||||||
public boolean handle(ResourcePackClientResponsePacket packet) {
|
public boolean handle(ResourcePackClientResponsePacket packet) {
|
||||||
switch (packet.getStatus()) {
|
switch (packet.getStatus()) {
|
||||||
case COMPLETED:
|
case COMPLETED:
|
||||||
masterServer.getLogger().info("Logged in " + player.getDisplayName() + " (" + player.getXuid() + ", " + player.getIdentity() + ")");
|
masterServer.getLogger().info("Logged in " + player.getAuthData().getName() + " (" + player.getAuthData().getXboxUUID() + ", " + player.getAuthData().getUUID() + ")");
|
||||||
player.sendStartGame();
|
player.sendStartGame();
|
||||||
break;
|
break;
|
||||||
case HAVE_ALL_PACKS:
|
case HAVE_ALL_PACKS:
|
||||||
|
@ -205,7 +214,7 @@ public class PacketHandler implements BedrockPacketHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(SetLocalPlayerAsInitializedPacket packet) {
|
public boolean handle(SetLocalPlayerAsInitializedPacket packet) {
|
||||||
masterServer.getLogger().debug("Player initialized: " + player.getDisplayName());
|
masterServer.getLogger().debug("Player initialized: " + player.getAuthData().getName());
|
||||||
|
|
||||||
// Handle the virtual host if specified
|
// Handle the virtual host if specified
|
||||||
GeyserConnectConfig.VirtualHostSection vhost = MasterServer.getInstance().getGeyserConnectConfig().getVhost();
|
GeyserConnectConfig.VirtualHostSection vhost = MasterServer.getInstance().getGeyserConnectConfig().getVhost();
|
||||||
|
@ -236,7 +245,7 @@ public class PacketHandler implements BedrockPacketHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the virtual host usage
|
// Log the virtual host usage
|
||||||
masterServer.getLogger().info(player.getDisplayName() + " is using virtualhost: " + address + ":" + port + (!online ? " (offline)" : ""));
|
masterServer.getLogger().info(player.getAuthData().getName() + " is using virtualhost: " + address + ":" + port + (!online ? " (offline)" : ""));
|
||||||
|
|
||||||
// Send the player to the wanted server
|
// Send the player to the wanted server
|
||||||
player.sendToServer(new Server(address, port, online, false));
|
player.sendToServer(new Server(address, port, online, false));
|
||||||
|
|
|
@ -68,11 +68,9 @@ public class GeyserProxyBootstrap implements GeyserBootstrap {
|
||||||
// Grab the config as text and replace static strings to the main config variables
|
// Grab the config as text and replace static strings to the main config variables
|
||||||
String text = new BufferedReader(new InputStreamReader(configFile, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
|
String text = new BufferedReader(new InputStreamReader(configFile, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
|
||||||
GeyserConnectConfig multiConfig = MasterServer.getInstance().getGeyserConnectConfig();
|
GeyserConnectConfig multiConfig = MasterServer.getInstance().getGeyserConnectConfig();
|
||||||
text = text.replace("PORT", String.valueOf(multiConfig.getGeyser().getPort()));
|
text = text.replaceAll("%MOTD%", multiConfig.getMotd());
|
||||||
text = text.replaceAll("MOTD", multiConfig.getMotd());
|
text = text.replace("%PLAYERS%", String.valueOf(multiConfig.getMaxPlayers()));
|
||||||
text = text.replace("PLAYERS", String.valueOf(multiConfig.getMaxPlayers()));
|
text = text.replace("%ALLOWPASSWORDAUTHENTICATION%", String.valueOf(multiConfig.getGeyser().isAllowPasswordAuthentication()));
|
||||||
text = text.replace("CACHECHUNKS", String.valueOf(multiConfig.getGeyser().isCacheChunks()));
|
|
||||||
text = text.replace("ALLOWPASSWORDAUTHENTICATION", String.valueOf(multiConfig.getGeyser().isAllowPasswordAuthentication()));
|
|
||||||
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
||||||
geyserConfig = objectMapper.readValue(text, GeyserProxyConfiguration.class);
|
geyserConfig = objectMapper.readValue(text, GeyserProxyConfiguration.class);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -26,35 +26,12 @@
|
||||||
package org.geysermc.connect.proxy;
|
package org.geysermc.connect.proxy;
|
||||||
|
|
||||||
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
||||||
import lombok.Getter;
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.common.AuthType;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connect.MasterServer;
|
|
||||||
import org.geysermc.connect.utils.Player;
|
|
||||||
import org.geysermc.connector.network.session.auth.AuthData;
|
|
||||||
|
|
||||||
public class GeyserProxySession extends GeyserSession {
|
public class GeyserProxySession extends GeyserSession {
|
||||||
|
|
||||||
private final BedrockServerSession bedrockServerSession;
|
|
||||||
@Getter
|
|
||||||
private Player player;
|
|
||||||
|
|
||||||
public GeyserProxySession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
|
public GeyserProxySession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
|
||||||
super(connector, bedrockServerSession);
|
super(connector, bedrockServerSession);
|
||||||
this.bedrockServerSession = bedrockServerSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAuthenticationData(AuthData authData) {
|
|
||||||
super.setAuthenticationData(authData);
|
|
||||||
|
|
||||||
player = MasterServer.getInstance().getTransferringPlayers().getIfPresent(authData.getXboxUUID());
|
|
||||||
if (player == null) {
|
|
||||||
bedrockServerSession.disconnect("Please connect to the master server and pick a server first!");
|
|
||||||
} else {
|
|
||||||
MasterServer.getInstance().getTransferringPlayers().invalidate(authData.getXboxUUID());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/GeyserConnect
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.connect.proxy;
|
|
||||||
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetLocalPlayerAsInitializedPacket;
|
|
||||||
import org.geysermc.connect.MasterServer;
|
|
||||||
import org.geysermc.connect.utils.Player;
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
|
||||||
import org.geysermc.connector.common.AuthType;
|
|
||||||
import org.geysermc.connector.network.UpstreamPacketHandler;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
|
||||||
|
|
||||||
public class GeyserProxyUpstreamPacketHandler extends UpstreamPacketHandler {
|
|
||||||
public GeyserProxyUpstreamPacketHandler(GeyserConnector connector, GeyserSession session) {
|
|
||||||
super(connector, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handle(SetLocalPlayerAsInitializedPacket packet) {
|
|
||||||
Player player = ((GeyserProxySession) session).getPlayer();
|
|
||||||
session.setRemoteAddress(player.getCurrentServer().getAddress());
|
|
||||||
session.setRemotePort(player.getCurrentServer().getPort());
|
|
||||||
session.setRemoteAuthType(player.getCurrentServer().isOnline() ? AuthType.ONLINE : AuthType.OFFLINE);
|
|
||||||
|
|
||||||
return super.handle(packet);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,50 +35,13 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class ProxyConnectorServerEventHandler extends ConnectorServerEventHandler {
|
public class ProxyConnectorServerEventHandler extends ConnectorServerEventHandler {
|
||||||
|
|
||||||
private final GeyserConnector connector;
|
|
||||||
|
|
||||||
public ProxyConnectorServerEventHandler(GeyserConnector connector) {
|
public ProxyConnectorServerEventHandler(GeyserConnector connector) {
|
||||||
super(connector);
|
super(connector);
|
||||||
this.connector = connector;
|
|
||||||
MasterServer.getInstance().getLogger().debug("Registered custom ConnectorServerEventHandler");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSessionCreation(BedrockServerSession bedrockServerSession) {
|
public void onSessionCreation(BedrockServerSession bedrockServerSession) {
|
||||||
super.onSessionCreation(bedrockServerSession);
|
super.onSessionCreation(bedrockServerSession);
|
||||||
|
bedrockServerSession.disconnect("Not sure how you managed it, but you shouldn't be here!");
|
||||||
// This doesn't clean up the old packet handler, so may cause a memory leak?
|
|
||||||
GeyserProxySession session = new GeyserProxySession(connector, bedrockServerSession);
|
|
||||||
bedrockServerSession.setPacketHandler(new GeyserProxyUpstreamPacketHandler(connector, session));
|
|
||||||
|
|
||||||
// Add another disconnect handler to remove the player on final disconnect
|
|
||||||
bedrockServerSession.addDisconnectHandler(disconnectReason -> {
|
|
||||||
// Make sure nothing is null before locating the player
|
|
||||||
if (MasterServer.getInstance() == null
|
|
||||||
|| session.getAuthData() == null
|
|
||||||
|| session.getAuthData().getXboxUUID() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = session.getPlayer();
|
|
||||||
if (player != null) {
|
|
||||||
MasterServer.getInstance().getLogger().debug("Player disconnected from Geyser proxy: " + player.getDisplayName() + " (" + disconnectReason + ")");
|
|
||||||
|
|
||||||
// Set the last disconnect time
|
|
||||||
MasterServer.getInstance().setLastDisconnectTime(System.currentTimeMillis());
|
|
||||||
|
|
||||||
int shutdownTime = MasterServer.getInstance().getGeyserConnectConfig().getGeyser().getShutdownTime();
|
|
||||||
|
|
||||||
if (shutdownTime != -1) {
|
|
||||||
MasterServer.getInstance().getGeneralThreadPool().schedule(() -> {
|
|
||||||
if (System.currentTimeMillis() - MasterServer.getInstance().getLastDisconnectTime() > shutdownTime * 1000L
|
|
||||||
&& connector != null
|
|
||||||
&& connector.getPlayers().size() <= 0) {
|
|
||||||
MasterServer.getInstance().shutdownGeyserProxy();
|
|
||||||
}
|
|
||||||
}, shutdownTime, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class JsonStorageManager extends AbstractStorageManager {
|
||||||
@Override
|
@Override
|
||||||
public void saveServers(Player player) {
|
public void saveServers(Player player) {
|
||||||
try {
|
try {
|
||||||
mapper.writeValue(dataFolder.resolve(player.getXuid() + ".json").toFile(), player.getServers());
|
mapper.writeValue(dataFolder.resolve(player.getAuthData().getXboxUUID() + ".json").toFile(), player.getServers());
|
||||||
} catch (IOException ignored) { }
|
} catch (IOException ignored) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class JsonStorageManager extends AbstractStorageManager {
|
||||||
List<Server> servers = new ArrayList<>();
|
List<Server> servers = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<Server> loadedServers = mapper.readValue(dataFolder.resolve(player.getXuid() + ".json").toFile(), new TypeReference<List<Server>>(){});
|
List<Server> loadedServers = mapper.readValue(dataFolder.resolve(player.getAuthData().getXboxUUID() + ".json").toFile(), new TypeReference<List<Server>>(){});
|
||||||
servers.addAll(loadedServers);
|
servers.addAll(loadedServers);
|
||||||
} catch (IOException ignored) { }
|
} catch (IOException ignored) { }
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class MySQLStorageManager extends AbstractStorageManager {
|
||||||
public void saveServers(Player player) {
|
public void saveServers(Player player) {
|
||||||
try {
|
try {
|
||||||
Statement updatePlayersServers = connection.createStatement();
|
Statement updatePlayersServers = connection.createStatement();
|
||||||
updatePlayersServers.executeUpdate("REPLACE INTO players(xuid, servers) VALUES('" + player.getXuid() + "', '" + mapper.writeValueAsString(player.getServers()) + "');");
|
updatePlayersServers.executeUpdate("REPLACE INTO players(xuid, servers) VALUES('" + player.getAuthData().getXboxUUID() + "', '" + mapper.writeValueAsString(player.getServers()) + "');");
|
||||||
updatePlayersServers.close();
|
updatePlayersServers.close();
|
||||||
} catch (IOException | SQLException ignored) { }
|
} catch (IOException | SQLException ignored) { }
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public class MySQLStorageManager extends AbstractStorageManager {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement getPlayersServers = connection.createStatement();
|
Statement getPlayersServers = connection.createStatement();
|
||||||
ResultSet rs = getPlayersServers.executeQuery("SELECT servers FROM players WHERE xuid='" + player.getXuid() + "';");
|
ResultSet rs = getPlayersServers.executeQuery("SELECT servers FROM players WHERE xuid='" + player.getAuthData().getXboxUUID() + "';");
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
List<Server> loadedServers = mapper.readValue(rs.getString("servers"), new TypeReference<List<Server>>(){});
|
List<Server> loadedServers = mapper.readValue(rs.getString("servers"), new TypeReference<List<Server>>(){});
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class SQLiteStorageManager extends AbstractStorageManager {
|
||||||
public void saveServers(Player player) {
|
public void saveServers(Player player) {
|
||||||
try {
|
try {
|
||||||
Statement updatePlayersServers = connection.createStatement();
|
Statement updatePlayersServers = connection.createStatement();
|
||||||
updatePlayersServers.executeUpdate("INSERT OR REPLACE INTO players(xuid, servers) VALUES('" + player.getXuid() + "', '" + mapper.writeValueAsString(player.getServers()) + "');");
|
updatePlayersServers.executeUpdate("INSERT OR REPLACE INTO players(xuid, servers) VALUES('" + player.getAuthData().getXboxUUID() + "', '" + mapper.writeValueAsString(player.getServers()) + "');");
|
||||||
updatePlayersServers.close();
|
updatePlayersServers.close();
|
||||||
} catch (IOException | SQLException ignored) { }
|
} catch (IOException | SQLException ignored) { }
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ public class SQLiteStorageManager extends AbstractStorageManager {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement getPlayersServers = connection.createStatement();
|
Statement getPlayersServers = connection.createStatement();
|
||||||
ResultSet rs = getPlayersServers.executeQuery("SELECT servers FROM players WHERE xuid='" + player.getXuid() + "';");
|
ResultSet rs = getPlayersServers.executeQuery("SELECT servers FROM players WHERE xuid='" + player.getAuthData().getXboxUUID() + "';");
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
List<Server> loadedServers = mapper.readValue(rs.getString("servers"), new TypeReference<List<Server>>() {});
|
List<Server> loadedServers = mapper.readValue(rs.getString("servers"), new TypeReference<List<Server>>() {});
|
||||||
|
|
|
@ -29,60 +29,16 @@ import com.nukkitx.nbt.*;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is mostly copied from core Geyser
|
* This class is mostly copied from core Geyser
|
||||||
*/
|
*/
|
||||||
public class PaletteManger {
|
public class PaletteManger {
|
||||||
|
|
||||||
public static final NbtList<NbtMap> BLOCK_PALETTE;
|
|
||||||
public static final NbtMap BIOMES_PALETTE;
|
|
||||||
public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
|
public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
|
||||||
|
|
||||||
private static final NbtMap EMPTY_TAG = NbtMap.EMPTY;
|
private static final NbtMap EMPTY_TAG = NbtMap.EMPTY;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
/* Load block palette */
|
|
||||||
// Build the air block entry
|
|
||||||
NbtMapBuilder mainBuilder = NbtMap.builder();
|
|
||||||
mainBuilder.putShort("id", (short) 0);
|
|
||||||
|
|
||||||
NbtMapBuilder blockBuilder = NbtMap.builder();
|
|
||||||
blockBuilder.putString("name", "minecraft:air");
|
|
||||||
blockBuilder.putInt("version", 17825806);
|
|
||||||
blockBuilder.put("states", NbtMap.EMPTY);
|
|
||||||
|
|
||||||
mainBuilder.put("block", blockBuilder.build());
|
|
||||||
|
|
||||||
// Build the block list with the entry
|
|
||||||
List<NbtMap> blocks = new ArrayList<>();
|
|
||||||
blocks.add(mainBuilder.build());
|
|
||||||
|
|
||||||
BLOCK_PALETTE = new NbtList<>(NbtType.COMPOUND, blocks);
|
|
||||||
|
|
||||||
/* Load biomes */
|
|
||||||
// Build a fake plains biome entry
|
|
||||||
NbtMapBuilder plainsBuilder = NbtMap.builder();
|
|
||||||
plainsBuilder.putFloat("blue_spores", 0f);
|
|
||||||
plainsBuilder.putFloat("white_ash", 0f);
|
|
||||||
plainsBuilder.putFloat("ash", 0f);
|
|
||||||
plainsBuilder.putFloat("temperature", 0f);
|
|
||||||
plainsBuilder.putFloat("red_spores", 0f);
|
|
||||||
plainsBuilder.putFloat("downfall", 0f);
|
|
||||||
|
|
||||||
plainsBuilder.put("minecraft:overworld_generation_rules", NbtMap.EMPTY);
|
|
||||||
plainsBuilder.put("minecraft:climate", NbtMap.EMPTY);
|
|
||||||
plainsBuilder.put("tags", NbtList.EMPTY);
|
|
||||||
|
|
||||||
// Add the fake plains to the map
|
|
||||||
NbtMapBuilder biomesBuilder = NbtMap.builder();
|
|
||||||
biomesBuilder.put("plains", plainsBuilder.build());
|
|
||||||
|
|
||||||
// Build the biomes palette
|
|
||||||
BIOMES_PALETTE = biomesBuilder.build();
|
|
||||||
|
|
||||||
/* Create empty chunk data */
|
/* Create empty chunk data */
|
||||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||||
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
|
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
|
||||||
|
|
|
@ -25,34 +25,39 @@
|
||||||
|
|
||||||
package org.geysermc.connect.utils;
|
package org.geysermc.connect.utils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.nukkitx.math.vector.Vector2f;
|
import com.nukkitx.math.vector.Vector2f;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
||||||
import com.nukkitx.protocol.bedrock.data.*;
|
import com.nukkitx.protocol.bedrock.data.*;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.connect.MasterServer;
|
import org.geysermc.connect.MasterServer;
|
||||||
|
import org.geysermc.connect.proxy.GeyserProxySession;
|
||||||
import org.geysermc.connect.ui.FormID;
|
import org.geysermc.connect.ui.FormID;
|
||||||
import org.geysermc.connect.ui.UIHandler;
|
import org.geysermc.connect.ui.UIHandler;
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
import org.geysermc.connector.common.AuthType;
|
||||||
|
import org.geysermc.connector.network.UpstreamPacketHandler;
|
||||||
|
import org.geysermc.connector.network.session.auth.AuthData;
|
||||||
import org.geysermc.connector.network.session.auth.BedrockClientData;
|
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_17_0;
|
||||||
|
import org.geysermc.connector.utils.DimensionUtils;
|
||||||
import org.geysermc.cumulus.Form;
|
import org.geysermc.cumulus.Form;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class Player {
|
public class Player {
|
||||||
|
|
||||||
private final String xuid;
|
private final AuthData authData;
|
||||||
private final UUID identity;
|
|
||||||
private final String displayName;
|
|
||||||
|
|
||||||
private final BedrockServerSession session;
|
private final BedrockServerSession session;
|
||||||
|
|
||||||
|
@ -71,11 +76,8 @@ public class Player {
|
||||||
@Setter
|
@Setter
|
||||||
private ServerCategory serverCategory;
|
private ServerCategory serverCategory;
|
||||||
|
|
||||||
public Player(JsonNode extraData, BedrockServerSession session) {
|
public Player(AuthData authData, BedrockServerSession session) {
|
||||||
this.xuid = extraData.get("XUID").asText();
|
this.authData = authData;
|
||||||
this.identity = UUID.fromString(extraData.get("identity").asText());
|
|
||||||
this.displayName = extraData.get("displayName").asText();
|
|
||||||
|
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
|
||||||
// Should fetch the servers from some form of db
|
// Should fetch the servers from some form of db
|
||||||
|
@ -128,7 +130,7 @@ public class Player {
|
||||||
startGamePacket.setWorldTemplateOptionLocked(false);
|
startGamePacket.setWorldTemplateOptionLocked(false);
|
||||||
|
|
||||||
startGamePacket.setLevelId("");
|
startGamePacket.setLevelId("");
|
||||||
startGamePacket.setLevelName("GeyserMulti");
|
startGamePacket.setLevelName("GeyserConnect");
|
||||||
startGamePacket.setPremiumWorldTemplateId("");
|
startGamePacket.setPremiumWorldTemplateId("");
|
||||||
startGamePacket.setCurrentTick(0);
|
startGamePacket.setCurrentTick(0);
|
||||||
startGamePacket.setEnchantmentSeed(0);
|
startGamePacket.setEnchantmentSeed(0);
|
||||||
|
@ -144,11 +146,6 @@ public class Player {
|
||||||
startGamePacket.setVanillaVersion("*");
|
startGamePacket.setVanillaVersion("*");
|
||||||
session.sendPacket(startGamePacket);
|
session.sendPacket(startGamePacket);
|
||||||
|
|
||||||
// Send a CreativeContentPacket - required for 1.16.100
|
|
||||||
CreativeContentPacket creativeContentPacket = new CreativeContentPacket();
|
|
||||||
creativeContentPacket.setContents(new ItemData[0]);
|
|
||||||
session.sendPacket(creativeContentPacket);
|
|
||||||
|
|
||||||
// Send an empty chunk
|
// Send an empty chunk
|
||||||
LevelChunkPacket data = new LevelChunkPacket();
|
LevelChunkPacket data = new LevelChunkPacket();
|
||||||
data.setChunkX(0);
|
data.setChunkX(0);
|
||||||
|
@ -160,9 +157,18 @@ public class Player {
|
||||||
|
|
||||||
// Send the biomes
|
// Send the biomes
|
||||||
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
|
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
|
||||||
biomeDefinitionListPacket.setDefinitions(PaletteManger.BIOMES_PALETTE);
|
biomeDefinitionListPacket.setDefinitions(BiomeTranslator.BIOMES);
|
||||||
session.sendPacket(biomeDefinitionListPacket);
|
session.sendPacket(biomeDefinitionListPacket);
|
||||||
|
|
||||||
|
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
|
||||||
|
entityPacket.setIdentifiers(EntityIdentifierRegistry.ENTITY_IDENTIFIERS);
|
||||||
|
session.sendPacket(entityPacket);
|
||||||
|
|
||||||
|
// Send a CreativeContentPacket - required for 1.16.100
|
||||||
|
CreativeContentPacket creativeContentPacket = new CreativeContentPacket();
|
||||||
|
creativeContentPacket.setContents(ItemRegistry.CREATIVE_ITEMS);
|
||||||
|
session.sendPacket(creativeContentPacket);
|
||||||
|
|
||||||
// Let the client know the player can spawn
|
// Let the client know the player can spawn
|
||||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||||
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||||
|
@ -206,33 +212,41 @@ public class Player {
|
||||||
* Send the player to the Geyser proxy server or straight to the bedrock server if it is
|
* Send the player to the Geyser proxy server or straight to the bedrock server if it is
|
||||||
*/
|
*/
|
||||||
public void connectToProxy() {
|
public void connectToProxy() {
|
||||||
// Use the clients connecting IP then fallback to the remote address from config
|
|
||||||
String address = clientData.getServerAddress().split(":")[0].trim();
|
|
||||||
if (address.isEmpty()) {
|
|
||||||
address = MasterServer.getInstance().getGeyserConnectConfig().getRemoteAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
int port = MasterServer.getInstance().getGeyserConnectConfig().getGeyser().getPort();
|
|
||||||
|
|
||||||
if (currentServer.isBedrock()) {
|
if (currentServer.isBedrock()) {
|
||||||
address = currentServer.getAddress();
|
TransferPacket transferPacket = new TransferPacket();
|
||||||
port = currentServer.getPort();
|
transferPacket.setAddress(currentServer.getAddress());
|
||||||
}
|
transferPacket.setPort(currentServer.getPort());
|
||||||
|
session.sendPacket(transferPacket);
|
||||||
|
} else {
|
||||||
|
GeyserProxySession geyserSession = new GeyserProxySession(GeyserConnector.getInstance(), session);
|
||||||
|
session.setPacketHandler(new UpstreamPacketHandler(GeyserConnector.getInstance(), geyserSession));
|
||||||
|
|
||||||
TransferPacket transferPacket = new TransferPacket();
|
geyserSession.getUpstream().getSession().setPacketCodec(session.getPacketCodec());
|
||||||
transferPacket.setAddress(address);
|
|
||||||
transferPacket.setPort(port);
|
// Set the block translation based off of version
|
||||||
session.sendPacket(transferPacket);
|
geyserSession.setBlockTranslator(BlockTranslator1_17_0.INSTANCE);
|
||||||
|
|
||||||
|
geyserSession.setAuthData(authData);
|
||||||
|
geyserSession.setClientData(clientData);
|
||||||
|
|
||||||
|
geyserSession.setDimension(DimensionUtils.THE_END);
|
||||||
|
|
||||||
|
geyserSession.setRemoteAddress(currentServer.getAddress());
|
||||||
|
geyserSession.setRemotePort(currentServer.getPort());
|
||||||
|
geyserSession.setRemoteAuthType(currentServer.isOnline() ? AuthType.ONLINE : AuthType.OFFLINE);
|
||||||
|
|
||||||
|
// Tell Geyser to handle the login
|
||||||
|
SetLocalPlayerAsInitializedPacket initializedPacket = new SetLocalPlayerAsInitializedPacket();
|
||||||
|
initializedPacket.setRuntimeEntityId(geyserSession.getPlayerEntity().getGeyserId());
|
||||||
|
session.getPacketHandler().handle(initializedPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendToServer(Server server) {
|
public void sendToServer(Server server) {
|
||||||
// Tell the user we are connecting them
|
// Tell the user we are connecting them
|
||||||
// This wont show up in a lot of cases as the client connects quite quickly
|
// This wont show up in a lot of cases as the client connects quite quickly
|
||||||
sendWindow(FormID.CONNECTING, UIHandler.getWaitingScreen(server));
|
if (!server.isOnline()) {
|
||||||
|
sendWindow(FormID.CONNECTING, UIHandler.getWaitingScreen(server));
|
||||||
if (!server.isBedrock()) {
|
|
||||||
// Create the Geyser instance if its not already running
|
|
||||||
MasterServer.getInstance().createGeyserProxy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the user over to the server
|
// Send the user over to the server
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
# The IP address that will listen for connections
|
# The IP address that will listen for connections
|
||||||
address: 0.0.0.0
|
address: 0.0.0.0
|
||||||
|
|
||||||
# The IP address remote clients use to connect, can be set to 'auto' to fetch from the web
|
|
||||||
remote-address: auto
|
|
||||||
|
|
||||||
# The port that will listen for connections
|
# The port that will listen for connections
|
||||||
port: 19132
|
port: 19132
|
||||||
|
|
||||||
|
@ -28,22 +25,12 @@ welcome-file: welcome.txt
|
||||||
|
|
||||||
# Config for the Geyser listener
|
# Config for the Geyser listener
|
||||||
geyser:
|
geyser:
|
||||||
# The port that will listen for connections
|
|
||||||
port: 19133
|
|
||||||
|
|
||||||
# Configures if chunk caching should be enabled or not.
|
|
||||||
cache-chunks: true
|
|
||||||
|
|
||||||
# If password authentication should be allowed in online mode.
|
# If password authentication should be allowed in online mode.
|
||||||
allow-password-authentication: false
|
allow-password-authentication: false
|
||||||
|
|
||||||
# If debug messages should be sent through console, has to be enabled in both places to work
|
# If debug messages should be sent through console, has to be enabled in both places to work
|
||||||
debug-mode: false
|
debug-mode: false
|
||||||
|
|
||||||
# The time to wait after the last player disconnects to shutdown the proxy
|
|
||||||
# In seconds, set to -1 to disable
|
|
||||||
shutdown-time: 300
|
|
||||||
|
|
||||||
# A global list of servers sent to all clients
|
# A global list of servers sent to all clients
|
||||||
servers:
|
servers:
|
||||||
- name: The Hive
|
- name: The Hive
|
||||||
|
|
|
@ -12,45 +12,70 @@ bedrock:
|
||||||
# There is no reason to change this unless you want to limit what IPs can connect to your server.
|
# There is no reason to change this unless you want to limit what IPs can connect to your server.
|
||||||
address: 0.0.0.0
|
address: 0.0.0.0
|
||||||
# The port that will listen for connections
|
# The port that will listen for connections
|
||||||
port: PORT
|
port: 19132
|
||||||
# Some hosting services change your Java port everytime you start the server and require the same port to be used for Bedrock.
|
# Some hosting services change your Java port everytime you start the server and require the same port to be used for Bedrock.
|
||||||
# This option makes the Bedrock port the same as the Java port every time you start the server.
|
# This option makes the Bedrock port the same as the Java port every time you start the server.
|
||||||
# This option is for the plugin version only.
|
# This option is for the plugin version only.
|
||||||
clone-remote-port: false
|
clone-remote-port: false
|
||||||
# The MOTD that will be broadcasted to Minecraft: Bedrock Edition clients. This is irrelevant if "passthrough-motd" is set to true
|
# The MOTD that will be broadcasted to Minecraft: Bedrock Edition clients. This is irrelevant if "passthrough-motd" is set to true
|
||||||
motd1: "MOTD"
|
# If either of these are empty, the respective string will default to "Geyser"
|
||||||
motd2: "MOTD"
|
motd1: "%MOTD%"
|
||||||
|
motd2: "%MOTD%"
|
||||||
# The Server Name that will be sent to Minecraft: Bedrock Edition clients. This is visible in both the pause menu and the settings menu.
|
# The Server Name that will be sent to Minecraft: Bedrock Edition clients. This is visible in both the pause menu and the settings menu.
|
||||||
server-name: "Geyser"
|
server-name: "Geyser"
|
||||||
|
# How much to compress network traffic to the Bedrock client. The higher the number, the more CPU usage used, but
|
||||||
|
# the smaller the bandwidth used. Does not have any effect below -1 or above 9. Set to -1 to disable.
|
||||||
|
compression-level: 6
|
||||||
|
# Whether to enable PROXY protocol or not for clients. You DO NOT WANT this feature unless you run UDP reverse proxy
|
||||||
|
# in front of your Geyser instance.
|
||||||
|
enable-proxy-protocol: false
|
||||||
|
# A list of allowed PROXY protocol speaking proxy IP addresses/subnets. Only effective when "enable-proxy-protocol" is enabled, and
|
||||||
|
# should really only be used when you are not able to use a proper firewall (usually true with shared hosting providers etc.).
|
||||||
|
# Keeping this list empty means there is no IP address whitelist.
|
||||||
|
# Both IP addresses and subnets are supported.
|
||||||
|
#proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16" ]
|
||||||
remote:
|
remote:
|
||||||
# The IP address of the remote (Java Edition) server
|
# The IP address of the remote (Java Edition) server
|
||||||
# If it is "auto", for standalone version the remote address will be set to 127.0.0.1,
|
# If it is "auto", for standalone version the remote address will be set to 127.0.0.1,
|
||||||
# for plugin versions, Geyser will attempt to find the best address to connect to.
|
# for plugin versions, Geyser will attempt to find the best address to connect to.
|
||||||
address: 127.0.0.1
|
address: auto
|
||||||
# The port of the remote (Java Edition) server
|
# The port of the remote (Java Edition) server
|
||||||
# For plugin versions, if address has been set to "auto", the port will also follow the server's listening port.
|
# For plugin versions, if address has been set to "auto", the port will also follow the server's listening port.
|
||||||
port: 25565
|
port: 25565
|
||||||
# Authentication type. Can be offline, online, or floodgate (see https://github.com/GeyserMC/Geyser/wiki/Floodgate).
|
# Authentication type. Can be offline, online, or floodgate (see https://github.com/GeyserMC/Geyser/wiki/Floodgate).
|
||||||
auth-type: online
|
auth-type: online
|
||||||
allow-password-authentication: ALLOWPASSWORDAUTHENTICATION
|
# Allow for password-based authentication methods through Geyser. Only useful in online mode.
|
||||||
|
# If this is false, users must authenticate to Microsoft using a code provided by Geyser on their desktop.
|
||||||
|
allow-password-authentication: %ALLOWPASSWORDAUTHENTICATION%
|
||||||
|
# Whether to enable PROXY protocol or not while connecting to the server.
|
||||||
|
# This is useful only when:
|
||||||
|
# 1) Your server supports PROXY protocol (it probably doesn't)
|
||||||
|
# 2) You run Velocity or BungeeCord with the option enabled in the proxy's main config.
|
||||||
|
# IF YOU DON'T KNOW WHAT THIS IS, DON'T TOUCH IT!
|
||||||
|
use-proxy-protocol: false
|
||||||
|
# Forward the hostname that the Bedrock client used to connect over to the Java server
|
||||||
|
# This is designed to be used for forced hosts on proxies
|
||||||
|
forward-hostname: false
|
||||||
|
|
||||||
# Floodgate uses encryption to ensure use from authorised sources.
|
# Floodgate uses encryption to ensure use from authorised sources.
|
||||||
# This should point to the public key generated by Floodgate (Bungee or CraftBukkit)
|
# This should point to the public key generated by Floodgate (Bungee or CraftBukkit)
|
||||||
# You can ignore this when not using Floodgate.
|
# You can ignore this when not using Floodgate.
|
||||||
floodgate-key-file: public-key.pem
|
floodgate-key-file: public-key.pem
|
||||||
|
|
||||||
## the Xbox/MCPE username is the key for the Java server auth-info
|
# The Xbox/Minecraft Bedrock username is the key for the Java server auth-info.
|
||||||
## this allows automatic configuration/login to the remote Java server
|
# This allows automatic configuration/login to the remote Java server.
|
||||||
## if you are brave/stupid enough to put your Mojang account info into
|
# If you are brave enough to put your Mojang account info into a config file.
|
||||||
## a config file
|
# Uncomment the lines below to enable this feature.
|
||||||
#userAuths:
|
#userAuths:
|
||||||
# bluerkelp2: # MCPE/Xbox username
|
# BedrockAccountUsername: # Your Minecraft: Bedrock Edition username
|
||||||
# email: not_really_my_email_address_mr_minecrafter53267@gmail.com # Mojang account email address
|
# email: javaccountemail@example.com # Your Minecraft: Java Edition email
|
||||||
# password: "this isn't really my password"
|
# password: javaccountpassword123 # Your Minecraft: Java Edition password
|
||||||
|
# microsoft-account: true # Whether the account is a Mojang or Microsoft account.
|
||||||
#
|
#
|
||||||
# herpderp40300499303040503030300500293858393589:
|
# bluerkelp2:
|
||||||
# email: herpderp@derpherp.com
|
# email: not_really_my_email_address_mr_minecrafter53267@gmail.com
|
||||||
# password: dooooo
|
# password: "this isn't really my password"
|
||||||
|
# microsoft-account: false
|
||||||
|
|
||||||
# Bedrock clients can freeze when opening up the command prompt for the first time if given a lot of commands.
|
# Bedrock clients can freeze when opening up the command prompt for the first time if given a lot of commands.
|
||||||
# Disabling this will prevent command suggestions from being sent and solve freezing for Bedrock clients.
|
# Disabling this will prevent command suggestions from being sent and solve freezing for Bedrock clients.
|
||||||
|
@ -71,8 +96,12 @@ legacy-ping-passthrough: false
|
||||||
# Increase if you are getting BrokenPipe errors.
|
# Increase if you are getting BrokenPipe errors.
|
||||||
ping-passthrough-interval: 3
|
ping-passthrough-interval: 3
|
||||||
|
|
||||||
# Maximum amount of players that can connect
|
# Whether to forward player ping to the server. While enabling this will allow Bedrock players to have more accurate
|
||||||
max-players: PLAYERS
|
# ping, it may also cause players to time out more easily.
|
||||||
|
forward-player-ping: false
|
||||||
|
|
||||||
|
# Maximum amount of players that can connect. This is only visual at this time and does not actually limit player count.
|
||||||
|
max-players: %PLAYERS%
|
||||||
|
|
||||||
# If debug messages should be sent through console
|
# If debug messages should be sent through console
|
||||||
debug-mode: false
|
debug-mode: false
|
||||||
|
@ -89,24 +118,47 @@ allow-third-party-capes: true
|
||||||
allow-third-party-ears: false
|
allow-third-party-ears: false
|
||||||
|
|
||||||
# Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat
|
# Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat
|
||||||
show-cooldown: true
|
# Can be title, actionbar or false
|
||||||
|
show-cooldown: title
|
||||||
|
|
||||||
|
# Controls if coordinates are shown to players.
|
||||||
|
show-coordinates: true
|
||||||
|
|
||||||
|
# If set, when a Bedrock player performs any emote, it will swap the offhand and mainhand items, just like the Java Edition keybind
|
||||||
|
# There are three options this can be set to:
|
||||||
|
# disabled - the default/fallback, which doesn't apply this workaround
|
||||||
|
# no-emotes - emotes will NOT be sent to other Bedrock clients and offhand will be swapped. This effectively disables all emotes from being seen.
|
||||||
|
# emotes-and-offhand - emotes will be sent to Bedrock clients and offhand will be swapped
|
||||||
|
emote-offhand-workaround: "disabled"
|
||||||
|
|
||||||
# The default locale if we dont have the one the client requested. Uncomment to not use the default system language.
|
# The default locale if we dont have the one the client requested. Uncomment to not use the default system language.
|
||||||
# default-locale: en_us
|
# default-locale: en_us
|
||||||
|
|
||||||
# Configures if chunk caching should be enabled or not. This keeps an individual
|
# Configures if chunk caching should be enabled or not. This keeps an individual
|
||||||
# record of each block the client loads in. While this feature does allow for a few
|
# record of each block the client loads in. This feature does allow for a few things
|
||||||
# things such as block break animations to show up in creative mode and among others,
|
# such as more accurate movement that causes less problems with anticheat (meaning
|
||||||
# it is HIGHLY recommended you disable this on a production environment as it can eat
|
# you're less likely to be banned) and allows block break animations to show up in
|
||||||
# up a lot of RAM. However, when using the Spigot version of Geyser, support for features
|
# creative mode (and other features). Although this increases RAM usage, it likely
|
||||||
# or implementations this allows is automatically enabled without the additional caching as
|
# won't have much of an effect for the vast majority of people. However, if you're
|
||||||
# Geyser has direct access to the server itself.
|
# running out of RAM or are in a RAM-sensitive environment, you may want to disable
|
||||||
cache-chunks: CACHECHUNKS
|
# this. When using the Spigot version of Geyser, support for features or
|
||||||
|
# implementations this allows is automatically enabled without the additional caching
|
||||||
|
# as Geyser has direct access to the server itself.
|
||||||
|
cache-chunks: true
|
||||||
|
|
||||||
# Specify how many days images will be cached to disk to save downloading them from the internet.
|
# Specify how many days images will be cached to disk to save downloading them from the internet.
|
||||||
# A value of 0 is disabled. (Default: 0)
|
# A value of 0 is disabled. (Default: 0)
|
||||||
cache-images: 0
|
cache-images: 0
|
||||||
|
|
||||||
|
# Allows custom skulls to be displayed. Keeping them enabled may cause a performance decrease on older/weaker devices.
|
||||||
|
allow-custom-skulls: true
|
||||||
|
|
||||||
|
# Whether to add (at this time, only) the furnace minecart as a separate item in the game, which normally does not exist in Bedrock Edition.
|
||||||
|
# This should only need to be disabled if using a proxy that does not use the "transfer packet" style of server switching.
|
||||||
|
# If this is disabled, furnace minecart items will be mapped to hopper minecart items.
|
||||||
|
# This option requires a restart of Geyser in order to change its setting.
|
||||||
|
add-non-bedrock-items: true
|
||||||
|
|
||||||
# Bedrock prevents building and displaying blocks above Y127 in the Nether -
|
# Bedrock prevents building and displaying blocks above Y127 in the Nether -
|
||||||
# enabling this config option works around that by changing the Nether dimension ID
|
# enabling this config option works around that by changing the Nether dimension ID
|
||||||
# to the End ID. The main downside to this is that the sky will resemble that of
|
# to the End ID. The main downside to this is that the sky will resemble that of
|
||||||
|
@ -114,9 +166,13 @@ cache-images: 0
|
||||||
above-bedrock-nether-building: false
|
above-bedrock-nether-building: false
|
||||||
|
|
||||||
# Force clients to load all resource packs if there are any.
|
# Force clients to load all resource packs if there are any.
|
||||||
# If set to false it allows the user to disconnect from the server if they don't
|
# If set to false, it allows the user to connect to the server even if they don't
|
||||||
# want to download the resource packs
|
# want to download the resource packs.
|
||||||
force-resource-packs: false
|
force-resource-packs: true
|
||||||
|
|
||||||
|
# Allows Xbox achievements to be unlocked.
|
||||||
|
# THIS DISABLES ALL COMMANDS FROM SUCCESSFULLY RUNNING FOR BEDROCK IN-GAME, as otherwise Bedrock thinks you are cheating.
|
||||||
|
xbox-achievements-enabled: false
|
||||||
|
|
||||||
# bStats is a stat tracker that is entirely anonymous and tracks only basic information
|
# bStats is a stat tracker that is entirely anonymous and tracks only basic information
|
||||||
# about Geyser, such as how many people are online, how many servers are using Geyser,
|
# about Geyser, such as how many people are online, how many servers are using Geyser,
|
||||||
|
@ -144,4 +200,8 @@ enable-proxy-connections: false
|
||||||
# 1400 is the default.
|
# 1400 is the default.
|
||||||
# mtu: 1400
|
# mtu: 1400
|
||||||
|
|
||||||
|
# Whether to use direct server methods to retrieve information such as block states.
|
||||||
|
# Turning this off for Spigot will stop NMS from being used but will have a performance impact.
|
||||||
|
use-adapters: true
|
||||||
|
|
||||||
config-version: 4
|
config-version: 4
|
Loading…
Add table
Reference in a new issue