diff --git a/pom.xml b/pom.xml
index edf4dcf..0251d97 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,8 +39,8 @@
com.nukkitx.protocol
- bedrock-v390
- 2.5.5
+ bedrock-v407
+ 2.6.0-SNAPSHOT
compile
diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java
index 3da9c44..ffe7cef 100644
--- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java
+++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java
@@ -6,15 +6,15 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import com.nukkitx.nbt.NBTInputStream;
+import com.nukkitx.nbt.NBTOutputStream;
import com.nukkitx.nbt.NbtUtils;
-import com.nukkitx.nbt.stream.NBTInputStream;
-import com.nukkitx.nbt.stream.NBTOutputStream;
-import com.nukkitx.nbt.tag.Tag;
import com.nukkitx.protocol.bedrock.BedrockClient;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.BedrockServer;
-import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
+import com.nukkitx.protocol.bedrock.v407.Bedrock_v407;
import com.nukkitx.proxypass.network.ProxyBedrockEventHandler;
+import io.netty.util.ResourceLeakDetector;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
@@ -37,7 +37,7 @@ public class ProxyPass {
public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
public static final YAMLMapper YAML_MAPPER = (YAMLMapper) new YAMLMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
public static final String MINECRAFT_VERSION;
- public static final BedrockPacketCodec CODEC = Bedrock_v390.V390_CODEC;
+ public static final BedrockPacketCodec CODEC = Bedrock_v407.V407_CODEC;
public static final int PROTOCOL_VERSION = CODEC.getProtocolVersion();
private static final DefaultPrettyPrinter PRETTY_PRINTER = new DefaultPrettyPrinter();
@@ -69,6 +69,7 @@ public class ProxyPass {
private Path dataDir;
public static void main(String[] args) {
+ ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID);
ProxyPass proxy = new ProxyPass();
try {
proxy.boot();
@@ -145,17 +146,17 @@ public void shutdown() {
}
}
- public void saveNBT(String dataName, Tag> dataTag) {
+ public void saveNBT(String dataName, Object dataTag) {
Path path = dataDir.resolve(dataName + ".dat");
try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
NBTOutputStream nbtOutputStream = NbtUtils.createNetworkWriter(outputStream)){
- nbtOutputStream.write(dataTag);
+ nbtOutputStream.writeTag(dataTag);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
- public Tag> loadNBT(String dataName) {
+ public Object loadNBT(String dataName) {
Path path = dataDir.resolve(dataName + ".dat");
try (InputStream inputStream = Files.newInputStream(path);
NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(inputStream)){
diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java
index 6f8aff1..727024b 100644
--- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java
+++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java
@@ -3,13 +3,14 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.nimbusds.jwt.SignedJWT;
-import com.nukkitx.nbt.stream.LittleEndianDataOutputStream;
-import com.nukkitx.nbt.stream.NBTOutputStream;
-import com.nukkitx.nbt.tag.CompoundTag;
-import com.nukkitx.nbt.tag.ListTag;
+import com.nukkitx.nbt.NBTOutputStream;
+import com.nukkitx.nbt.NbtList;
+import com.nukkitx.nbt.NbtMap;
+import com.nukkitx.nbt.NbtType;
+import com.nukkitx.nbt.util.stream.LittleEndianDataOutputStream;
import com.nukkitx.protocol.bedrock.BedrockClientSession;
-import com.nukkitx.protocol.bedrock.data.ContainerId;
-import com.nukkitx.protocol.bedrock.data.ItemData;
+import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
+import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler;
import com.nukkitx.protocol.bedrock.packet.*;
import com.nukkitx.protocol.bedrock.util.EncryptionUtils;
@@ -56,25 +57,25 @@ public boolean handle(ServerToClientHandshakePacket packet) {
}
public boolean handle(AvailableEntityIdentifiersPacket packet) {
- proxy.saveNBT("entity_identifiers", packet.getTag());
+ proxy.saveNBT("entity_identifiers", packet.getIdentifiers());
return false;
}
public boolean handle(BiomeDefinitionListPacket packet) {
- proxy.saveNBT("biome_definitions", packet.getTag());
+ proxy.saveNBT("biome_definitions", packet.getDefinitions());
return false;
}
public boolean handle(StartGamePacket packet) {
Map legacyBlocks = new HashMap<>();
- for (CompoundTag entry : packet.getBlockPalette().getValue()) {
+ for (NbtMap entry : packet.getBlockPalette()) {
legacyBlocks.putIfAbsent(entry.getCompound("block").getString("name"), (int) entry.getShort("id"));
}
proxy.saveJson("legacy_block_ids.json", sortMap(legacyBlocks));
- List palette = new ArrayList<>(packet.getBlockPalette().getValue());
+ List palette = new ArrayList<>(packet.getBlockPalette());
palette.sort(Comparator.comparingInt(value -> value.getShort("id")));
- proxy.saveNBT("runtime_block_states", new ListTag<>("", CompoundTag.class, palette));
+ proxy.saveNBT("runtime_block_states", new NbtList<>(NbtType.COMPOUND, palette));
BlockPaletteUtils.convertToJson(proxy, palette);
List itemData = new ArrayList<>();
@@ -107,31 +108,42 @@ public boolean handle(DisconnectPacket packet) {
return false;
}
- @Override
- public boolean handle(InventoryContentPacket packet) {
- if (packet.getContainerId() == ContainerId.CREATIVE) {
- List entries = new ArrayList<>();
- for (ItemData data : packet.getContents()) {
- int id = data.getId();
- Integer damage = data.getDamage() == 0 ? null : (int) data.getDamage();
-
- CompoundTag tag = data.getTag();
- String tagData = null;
- if (tag != null) {
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- try (NBTOutputStream stream = new NBTOutputStream(new LittleEndianDataOutputStream(byteArrayOutputStream))) {
- stream.write(tag);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- tagData = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
+ private void dumpCreativeItems(ItemData[] contents) {
+ List entries = new ArrayList<>();
+ for (ItemData data : contents) {
+ int id = data.getId();
+ Integer damage = data.getDamage() == 0 ? null : (int) data.getDamage();
+
+ NbtMap tag = data.getTag();
+ String tagData = null;
+ if (tag != null) {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ try (NBTOutputStream stream = new NBTOutputStream(new LittleEndianDataOutputStream(byteArrayOutputStream))) {
+ stream.writeTag(tag);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
- entries.add(new CreativeItemEntry(id, damage, tagData));
+ tagData = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
}
+ entries.add(new CreativeItemEntry(id, damage, tagData));
+ }
- CreativeItems items = new CreativeItems(entries);
+ CreativeItems items = new CreativeItems(entries);
- proxy.saveJson("creative_items.json", items);
+ proxy.saveJson("creative_items.json", items);
+ }
+
+ @Override
+ public boolean handle(CreativeContentPacket packet) {
+ dumpCreativeItems(packet.getEntries().values().toArray(new ItemData[0]));
+ return false;
+ }
+
+ // Pre 1.16 method of Creative Items
+ @Override
+ public boolean handle(InventoryContentPacket packet) {
+ if (packet.getContainerId() == ContainerId.CREATIVE) {
+ dumpCreativeItems(packet.getContents());
}
return false;
}
diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java
index 269663b..a5fd088 100644
--- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java
+++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java
@@ -5,11 +5,13 @@
import com.nukkitx.protocol.bedrock.BedrockPacket;
import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.BedrockSession;
+import com.nukkitx.protocol.bedrock.exception.PacketSerializeException;
import com.nukkitx.protocol.bedrock.handler.BatchHandler;
import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler;
import com.nukkitx.protocol.bedrock.util.EncryptionUtils;
import com.nukkitx.proxypass.ProxyPass;
import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
@@ -131,14 +133,18 @@ public void handle(BedrockSession session, ByteBuf compressed, Collection ProxyPass.PROTOCOL_VERSION) {
- status.setStatus(PlayStatusPacket.Status.FAILED_SERVER);
+ status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_SERVER_OLD);
} else {
- status.setStatus(PlayStatusPacket.Status.FAILED_CLIENT);
+ status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_CLIENT_OLD);
}
}
session.setPacketCodec(ProxyPass.CODEC);
@@ -126,7 +127,9 @@ public boolean handle(LoginPacket packet) {
private void initializeProxySession() {
log.debug("Initializing proxy session");
- proxy.newClient().connect(proxy.getTargetAddress()).whenComplete((downstream, throwable) -> {
+ BedrockClient client = proxy.newClient();
+ client.setRakNetVersion(10);
+ client.connect(proxy.getTargetAddress()).whenComplete((downstream, throwable) -> {
if (throwable != null) {
log.error("Unable to connect to downstream server " + proxy.getTargetAddress(), throwable);
return;
@@ -153,8 +156,8 @@ private void initializeProxySession() {
login.setProtocolVersion(ProxyPass.PROTOCOL_VERSION);
downstream.sendPacketImmediately(login);
- this.session.setBatchedHandler(proxySession.getUpstreamBatchHandler());
- downstream.setBatchedHandler(proxySession.getDownstreamTailHandler());
+ this.session.setBatchHandler(proxySession.getUpstreamBatchHandler());
+ downstream.setBatchHandler(proxySession.getDownstreamTailHandler());
downstream.setLogging(true);
downstream.setPacketHandler(new DownstreamPacketHandler(downstream, proxySession, this.proxy));
diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/BlockPaletteUtils.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/BlockPaletteUtils.java
index 43e9d99..886926c 100644
--- a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/BlockPaletteUtils.java
+++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/BlockPaletteUtils.java
@@ -1,8 +1,8 @@
package com.nukkitx.proxypass.network.bedrock.util;
import com.fasterxml.jackson.annotation.JsonInclude;
-import com.nukkitx.nbt.TagType;
-import com.nukkitx.nbt.tag.CompoundTag;
+import com.nukkitx.nbt.NbtMap;
+import com.nukkitx.nbt.NbtType;
import com.nukkitx.proxypass.ProxyPass;
import lombok.Value;
@@ -13,23 +13,23 @@
public class BlockPaletteUtils {
- public static void convertToJson(ProxyPass proxy, List tags) {
+ public static void convertToJson(ProxyPass proxy, List tags) {
List palette = new ArrayList<>(tags.size());
- for (CompoundTag tag : tags) {
+ for (NbtMap tag : tags) {
int id = tag.getShort("id");
- CompoundTag blockTag = tag.getCompound("block");
+ NbtMap blockTag = tag.getCompound("block");
String name = blockTag.getString("name");
Map states = new LinkedHashMap<>();
- blockTag.getCompound("states").getValue().forEach((key, value) -> {
- states.put(key, new BlockState(value.getValue(), TagType.byClass(value.getClass()).getId()));
+ blockTag.getCompound("states").forEach((key, value) -> {
+ states.put(key, new BlockState(value, NbtType.byClass(value.getClass()).getId()));
});
Integer meta = null;
- if (tag.contains("meta")) {
+ if (tag.containsKey("meta")) {
meta = (int) tag.getShort("meta");
}
palette.add(new Entry(id, meta, name, states));
diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java
index 154c337..e2c51c9 100644
--- a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java
+++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java
@@ -1,10 +1,10 @@
package com.nukkitx.proxypass.network.bedrock.util;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.nukkitx.nbt.NBTOutputStream;
+import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtUtils;
-import com.nukkitx.nbt.stream.NBTOutputStream;
-import com.nukkitx.nbt.tag.CompoundTag;
-import com.nukkitx.protocol.bedrock.data.*;
+import com.nukkitx.protocol.bedrock.data.inventory.*;
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
import com.nukkitx.proxypass.ProxyPass;
import lombok.AllArgsConstructor;
@@ -27,21 +27,21 @@ public static void writeRecipes(CraftingDataPacket packet, ProxyPass proxy) {
for (CraftingData craftingData : packet.getCraftingData()) {
CraftingDataEntry entry = new CraftingDataEntry();
- CraftingType type = craftingData.getType();
+ CraftingDataType type = craftingData.getType();
entry.type = type.ordinal();
- if (type != CraftingType.MULTI) {
+ if (type != CraftingDataType.MULTI) {
entry.block = craftingData.getCraftingTag();
} else {
entry.uuid = craftingData.getUuid();
}
- if (type == CraftingType.SHAPED || type == CraftingType.SHAPELESS || type == CraftingType.SHAPELESS_CHEMISTRY || type == CraftingType.SHULKER_BOX || type == CraftingType.SHAPED_CHEMISTRY) {
+ if (type == CraftingDataType.SHAPED || type == CraftingDataType.SHAPELESS || type == CraftingDataType.SHAPELESS_CHEMISTRY || type == CraftingDataType.SHULKER_BOX || type == CraftingDataType.SHAPED_CHEMISTRY) {
entry.id = craftingData.getRecipeId();
entry.priority = craftingData.getPriority();
entry.output = writeItemArray(craftingData.getOutputs(), true);
}
- if (type == CraftingType.SHAPED || type == CraftingType.SHAPED_CHEMISTRY) {
+ if (type == CraftingDataType.SHAPED || type == CraftingDataType.SHAPED_CHEMISTRY) {
int charCounter = 0;
ItemData[] inputs = craftingData.getInputs();
@@ -81,11 +81,11 @@ public static void writeRecipes(CraftingDataPacket packet, ProxyPass proxy) {
}
entry.input = itemMap;
}
- if (type == CraftingType.SHAPELESS || type == CraftingType.SHAPELESS_CHEMISTRY || type == CraftingType.SHULKER_BOX) {
+ if (type == CraftingDataType.SHAPELESS || type == CraftingDataType.SHAPELESS_CHEMISTRY || type == CraftingDataType.SHULKER_BOX) {
entry.input = writeItemArray(craftingData.getInputs(), false);
}
- if (type == CraftingType.FURNACE || type == CraftingType.FURNACE_DATA) {
+ if (type == CraftingDataType.FURNACE || type == CraftingDataType.FURNACE_DATA) {
Integer damage = craftingData.getInputDamage();
if (damage == 0x7fff) damage = -1;
if (damage == 0) damage = null;
@@ -111,11 +111,11 @@ private static Item[] writeItemArray(ItemData[] inputs, boolean output) {
return outputs.toArray(new Item[0]);
}
- private static String nbtToBase64(CompoundTag tag) {
+ private static String nbtToBase64(NbtMap tag) {
if (tag != null) {
ByteArrayOutputStream tagStream = new ByteArrayOutputStream();
try (NBTOutputStream writer = NbtUtils.createWriterLE(tagStream)) {
- writer.write(tag);
+ writer.writeTag(tag);
} catch (IOException e) {
throw new RuntimeException(e);
}