Add multi-version support, move to static block and biome palettes and update build

This commit is contained in:
rtm516 2020-08-22 21:29:28 +01:00
parent ba3c4a76e8
commit 1f911d42ae
No known key found for this signature in database
GPG key ID: 331715B8B007C67A
5 changed files with 51 additions and 26 deletions

View file

@ -29,6 +29,7 @@ import com.nukkitx.protocol.bedrock.*;
import com.nukkitx.protocol.bedrock.v408.Bedrock_v408; import com.nukkitx.protocol.bedrock.v408.Bedrock_v408;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.connector.network.BedrockProtocol;
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;
@ -47,8 +48,6 @@ import java.util.concurrent.ScheduledExecutorService;
public class MasterServer { public class MasterServer {
public static final BedrockPacketCodec CODEC = Bedrock_v408.V408_CODEC;
private final Timer timer; private final Timer timer;
private BedrockServer bdServer; private BedrockServer bdServer;
private BedrockPong bdPong; private BedrockPong bdPong;
@ -134,7 +133,7 @@ public class MasterServer {
bdPong.setMaximumPlayerCount(geyserConnectConfig.getMaxPlayers()); bdPong.setMaximumPlayerCount(geyserConnectConfig.getMaxPlayers());
bdPong.setGameType("Survival"); bdPong.setGameType("Survival");
bdPong.setIpv4Port(port); bdPong.setIpv4Port(port);
bdPong.setProtocolVersion(MasterServer.CODEC.getProtocolVersion()); bdPong.setProtocolVersion(BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion());
bdPong.setVersion(null); // Server tries to connect either way and it looks better bdPong.setVersion(null); // Server tries to connect either way and it looks better
bdServer.setHandler(new BedrockServerEventHandler() { bdServer.setHandler(new BedrockServerEventHandler() {

View file

@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.nimbusds.jose.JWSObject; import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory; import com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory;
import com.nukkitx.network.util.DisconnectReason; import com.nukkitx.network.util.DisconnectReason;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.data.AttributeData; import com.nukkitx.protocol.bedrock.data.AttributeData;
import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler; import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler;
@ -44,7 +45,9 @@ import org.geysermc.connect.ui.FormID;
import org.geysermc.connect.ui.UIHandler; import org.geysermc.connect.ui.UIHandler;
import org.geysermc.connect.utils.Player; import org.geysermc.connect.utils.Player;
import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.attribute.AttributeType;
import org.geysermc.connector.network.BedrockProtocol;
import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.AttributeUtils;
import org.geysermc.connector.utils.LanguageUtils;
import java.io.IOException; import java.io.IOException;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
@ -83,20 +86,20 @@ public class PacketHandler implements BedrockPacketHandler {
public boolean handle(LoginPacket packet) { public boolean handle(LoginPacket packet) {
masterServer.getLogger().debug("Login: " + packet.toString()); masterServer.getLogger().debug("Login: " + packet.toString());
// Check the protocol version is correct BedrockPacketCodec packetCodec = BedrockProtocol.getBedrockCodec(packet.getProtocolVersion());
int protocol = packet.getProtocolVersion(); if (packetCodec == null) {
if (protocol != MasterServer.CODEC.getProtocolVersion()) { session.setPacketCodec(BedrockProtocol.DEFAULT_BEDROCK_CODEC);
PlayStatusPacket status = new PlayStatusPacket(); PlayStatusPacket status = new PlayStatusPacket();
if (protocol > MasterServer.CODEC.getProtocolVersion()) { if (packet.getProtocolVersion() > BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()) {
status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_SERVER_OLD); status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_SERVER_OLD);
} else { } else if (packet.getProtocolVersion() < BedrockProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()) {
status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_CLIENT_OLD); status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_CLIENT_OLD);
} }
session.sendPacket(status); session.sendPacket(status);
} }
// Set the session codec // Set the session codec
session.setPacketCodec(MasterServer.CODEC); session.setPacketCodec(packetCodec);
// Read the raw chain data // Read the raw chain data
JsonNode rawChainData; JsonNode rawChainData;

View file

@ -28,8 +28,8 @@ package org.geysermc.connect.utils;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import net.minecrell.terminalconsole.SimpleTerminalConsole; import net.minecrell.terminalconsole.SimpleTerminalConsole;
import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.config.Configurator;
import org.geysermc.connector.GeyserLogger;
import org.geysermc.connect.MasterServer; import org.geysermc.connect.MasterServer;
import org.geysermc.connector.GeyserLogger;
import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.common.ChatColor;
@Log4j2 @Log4j2

View file

@ -31,36 +31,59 @@ import org.geysermc.connector.utils.FileUtils;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
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_PALLETE; public static final NbtList<NbtMap> BLOCK_PALETTE;
public static final NbtMap BIOMES_PALLETE; 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 */ /* Load block palette */
InputStream stream = FileUtils.getResource("bedrock/runtime_block_states.dat"); // Build the air block entry
NbtMapBuilder mainBuilder = NbtMap.builder();
mainBuilder.putShort("id", (short) 0);
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) { NbtMapBuilder blockBuilder = NbtMap.builder();
BLOCK_PALLETE = (NbtList<NbtMap>) nbtInputStream.readTag(); blockBuilder.putString("name", "minecraft:air");
} catch (Exception e) { blockBuilder.putInt("version", 17825806);
throw new AssertionError("Unable to get blocks from runtime block states", e); 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 */ /* Load biomes */
stream = FileUtils.getResource("bedrock/biome_definitions.dat"); // 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);
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)){ plainsBuilder.put("minecraft:overworld_generation_rules", NbtMap.EMPTY);
BIOMES_PALLETE = (NbtMap) nbtInputStream.readTag(); plainsBuilder.put("minecraft:climate", NbtMap.EMPTY);
} catch (Exception e) { plainsBuilder.put("tags", NbtList.EMPTY);
throw new AssertionError("Failed to get biomes from biome definitions", e);
} // 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()) {

View file

@ -128,7 +128,7 @@ public class Player {
startGamePacket.setCurrentTick(0); startGamePacket.setCurrentTick(0);
startGamePacket.setEnchantmentSeed(0); startGamePacket.setEnchantmentSeed(0);
startGamePacket.setMultiplayerCorrelationId(""); startGamePacket.setMultiplayerCorrelationId("");
startGamePacket.setBlockPalette(PaletteManger.BLOCK_PALLETE); startGamePacket.setBlockPalette(PaletteManger.BLOCK_PALETTE);
startGamePacket.setVanillaVersion("*"); startGamePacket.setVanillaVersion("*");
session.sendPacket(startGamePacket); session.sendPacket(startGamePacket);
@ -143,7 +143,7 @@ public class Player {
// Send the biomes // Send the biomes
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket(); BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
biomeDefinitionListPacket.setDefinitions(PaletteManger.BIOMES_PALLETE); biomeDefinitionListPacket.setDefinitions(PaletteManger.BIOMES_PALETTE);
session.sendPacket(biomeDefinitionListPacket); session.sendPacket(biomeDefinitionListPacket);
// Let the client know the player can spawn // Let the client know the player can spawn