mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-28 23:38:32 +01:00
Initial support for 1.19.30 Bedrock
This commit is contained in:
parent
77827d5cf5
commit
e64e12ff98
10 changed files with 66 additions and 41 deletions
|
@ -31,7 +31,7 @@ object Versions {
|
||||||
const val gsonVersion = "2.3.1" // Provided by Spigot 1.8.8
|
const val gsonVersion = "2.3.1" // Provided by Spigot 1.8.8
|
||||||
const val nbtVersion = "2.1.0"
|
const val nbtVersion = "2.1.0"
|
||||||
const val websocketVersion = "1.5.1"
|
const val websocketVersion = "1.5.1"
|
||||||
const val protocolVersion = "0bd459f"
|
const val protocolVersion = "f0feacd"
|
||||||
const val raknetVersion = "1.6.28-20220125.214016-6"
|
const val raknetVersion = "1.6.28-20220125.214016-6"
|
||||||
const val mcauthlibVersion = "d9d773e"
|
const val mcauthlibVersion = "d9d773e"
|
||||||
const val mcprotocollibversion = "9f78bd5"
|
const val mcprotocollibversion = "9f78bd5"
|
||||||
|
|
|
@ -30,7 +30,7 @@ dependencies {
|
||||||
// Network libraries
|
// Network libraries
|
||||||
implementation("org.java-websocket", "Java-WebSocket", Versions.websocketVersion)
|
implementation("org.java-websocket", "Java-WebSocket", Versions.websocketVersion)
|
||||||
|
|
||||||
api("com.github.CloudburstMC.Protocol", "bedrock-v544", Versions.protocolVersion) {
|
api("com.github.CloudburstMC.Protocol", "bedrock-v553", Versions.protocolVersion) {
|
||||||
exclude("com.nukkitx.network", "raknet")
|
exclude("com.nukkitx.network", "raknet")
|
||||||
exclude("com.nukkitx", "nbt")
|
exclude("com.nukkitx", "nbt")
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.geyser.network;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPong;
|
import com.nukkitx.protocol.bedrock.BedrockPong;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockServerEventHandler;
|
import com.nukkitx.protocol.bedrock.BedrockServerEventHandler;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
||||||
|
import com.nukkitx.protocol.bedrock.v553.Bedrock_v553;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.DefaultEventLoopGroup;
|
import io.netty.channel.DefaultEventLoopGroup;
|
||||||
|
@ -171,7 +172,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
|
||||||
@Override
|
@Override
|
||||||
public void onSessionCreation(@Nonnull BedrockServerSession bedrockServerSession) {
|
public void onSessionCreation(@Nonnull BedrockServerSession bedrockServerSession) {
|
||||||
try {
|
try {
|
||||||
bedrockServerSession.setPacketCodec(GameProtocol.DEFAULT_BEDROCK_CODEC);
|
bedrockServerSession.setPacketCodec(Bedrock_v553.V553_CODEC); // Has the RequestNetworkSettingsPacket
|
||||||
bedrockServerSession.setLogging(true);
|
bedrockServerSession.setLogging(true);
|
||||||
bedrockServerSession.setCompressionLevel(geyser.getConfig().getBedrock().getCompressionLevel());
|
bedrockServerSession.setCompressionLevel(geyser.getConfig().getBedrock().getCompressionLevel());
|
||||||
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(geyser, new GeyserSession(geyser, bedrockServerSession, eventLoopGroup.next())));
|
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(geyser, new GeyserSession(geyser, bedrockServerSession, eventLoopGroup.next())));
|
||||||
|
|
|
@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
import com.nukkitx.protocol.bedrock.v527.Bedrock_v527;
|
import com.nukkitx.protocol.bedrock.v527.Bedrock_v527;
|
||||||
import com.nukkitx.protocol.bedrock.v534.Bedrock_v534;
|
import com.nukkitx.protocol.bedrock.v534.Bedrock_v534;
|
||||||
import com.nukkitx.protocol.bedrock.v544.Bedrock_v544;
|
import com.nukkitx.protocol.bedrock.v544.Bedrock_v544;
|
||||||
|
import com.nukkitx.protocol.bedrock.v553.Bedrock_v553;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -71,6 +72,7 @@ public final class GameProtocol {
|
||||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||||
.minecraftVersion("1.19.21/1.19.22")
|
.minecraftVersion("1.19.21/1.19.22")
|
||||||
.build());
|
.build());
|
||||||
|
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v553.V553_CODEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -856,4 +856,11 @@ public class LoggingPacketHandler implements BedrockPacketHandler {
|
||||||
public boolean handle(FilterTextPacket packet) {
|
public boolean handle(FilterTextPacket packet) {
|
||||||
return defaultHandler(packet);
|
return defaultHandler(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1.19.30 new packet
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(RequestNetworkSettingsPacket packet) {
|
||||||
|
return defaultHandler(packet);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,7 @@ package org.geysermc.geyser.network;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPacket;
|
import com.nukkitx.protocol.bedrock.BedrockPacket;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
import com.nukkitx.protocol.bedrock.data.ExperimentData;
|
import com.nukkitx.protocol.bedrock.data.ExperimentData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.PacketCompressionAlgorithm;
|
||||||
import com.nukkitx.protocol.bedrock.data.ResourcePackType;
|
import com.nukkitx.protocol.bedrock.data.ResourcePackType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
@ -61,6 +62,20 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||||
return translateAndDefault(packet);
|
return translateAndDefault(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(RequestNetworkSettingsPacket packet) {
|
||||||
|
// New since 1.19.30 - sent before login packet
|
||||||
|
PacketCompressionAlgorithm algorithm = PacketCompressionAlgorithm.ZLIB;
|
||||||
|
|
||||||
|
NetworkSettingsPacket responsePacket = new NetworkSettingsPacket();
|
||||||
|
responsePacket.setCompressionAlgorithm(algorithm);
|
||||||
|
responsePacket.setCompressionThreshold(512);
|
||||||
|
session.sendUpstreamPacketImmediately(responsePacket);
|
||||||
|
|
||||||
|
session.getUpstream().getSession().setCompression(algorithm);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(LoginPacket loginPacket) {
|
public boolean handle(LoginPacket loginPacket) {
|
||||||
if (geyser.isShuttingDown()) {
|
if (geyser.isShuttingDown()) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import com.nukkitx.nbt.NbtMap;
|
||||||
import com.nukkitx.nbt.NbtUtils;
|
import com.nukkitx.nbt.NbtUtils;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
@ -171,7 +172,7 @@ public class RecipeRegistryPopulator {
|
||||||
/* Convert end */
|
/* Convert end */
|
||||||
|
|
||||||
return CraftingData.fromShaped(uuid.toString(), shape.get(0).length(), shape.size(),
|
return CraftingData.fromShaped(uuid.toString(), shape.get(0).length(), shape.size(),
|
||||||
inputs, Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
||||||
}
|
}
|
||||||
List<ItemData> inputs = new ObjectArrayList<>();
|
List<ItemData> inputs = new ObjectArrayList<>();
|
||||||
for (JsonNode entry : node.get("inputs")) {
|
for (JsonNode entry : node.get("inputs")) {
|
||||||
|
@ -191,10 +192,10 @@ public class RecipeRegistryPopulator {
|
||||||
if (type == 5) {
|
if (type == 5) {
|
||||||
// Shulker box
|
// Shulker box
|
||||||
return CraftingData.fromShulkerBox(uuid.toString(),
|
return CraftingData.fromShulkerBox(uuid.toString(),
|
||||||
inputs, Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
||||||
}
|
}
|
||||||
return CraftingData.fromShapeless(uuid.toString(),
|
return CraftingData.fromShapeless(uuid.toString(),
|
||||||
inputs, Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ItemData getBedrockItemFromIdentifierJson(ItemMapping mapping, JsonNode itemNode) {
|
private static ItemData getBedrockItemFromIdentifierJson(ItemMapping mapping, JsonNode itemNode) {
|
||||||
|
|
|
@ -62,7 +62,8 @@ public final class SessionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeSession(GeyserSession session) {
|
public void removeSession(GeyserSession session) {
|
||||||
if (sessions.remove(session.getPlayerEntity().getUuid()) == null) {
|
UUID uuid = session.getPlayerEntity().getUuid();
|
||||||
|
if (uuid == null || sessions.remove(uuid) == null) {
|
||||||
// Connection was likely pending
|
// Connection was likely pending
|
||||||
pendingSessions.remove(session);
|
pendingSessions.remove(session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,10 @@ import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeDa
|
||||||
import com.github.steveice10.mc.protocol.data.game.recipe.data.SmithingRecipeData;
|
import com.github.steveice10.mc.protocol.data.game.recipe.data.SmithingRecipeData;
|
||||||
import com.github.steveice10.mc.protocol.data.game.recipe.data.StoneCuttingRecipeData;
|
import com.github.steveice10.mc.protocol.data.game.recipe.data.StoneCuttingRecipeData;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket;
|
||||||
import com.nukkitx.nbt.NbtMap;
|
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.inventory.descriptor.DefaultDescriptor;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
|
||||||
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
@ -99,8 +100,8 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
}
|
}
|
||||||
// Strip NBT - tools won't appear in the recipe book otherwise
|
// Strip NBT - tools won't appear in the recipe book otherwise
|
||||||
output = output.toBuilder().tag(null).build();
|
output = output.toBuilder().tag(null).build();
|
||||||
ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
|
ItemDescriptorWithCount[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
|
||||||
for (ItemData[] inputs : inputCombinations) {
|
for (ItemDescriptorWithCount[] inputs : inputCombinations) {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
|
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
|
||||||
Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId));
|
Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId));
|
||||||
|
@ -116,8 +117,8 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
}
|
}
|
||||||
// See above
|
// See above
|
||||||
output = output.toBuilder().tag(null).build();
|
output = output.toBuilder().tag(null).build();
|
||||||
ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
|
ItemDescriptorWithCount[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
|
||||||
for (ItemData[] inputs : inputCombinations) {
|
for (ItemDescriptorWithCount[] inputs : inputCombinations) {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
craftingDataPacket.getCraftingData().add(CraftingData.fromShaped(uuid.toString(),
|
craftingDataPacket.getCraftingData().add(CraftingData.fromShaped(uuid.toString(),
|
||||||
shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs),
|
shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs),
|
||||||
|
@ -141,14 +142,14 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
SmithingRecipeData recipeData = (SmithingRecipeData) recipe.getData();
|
SmithingRecipeData recipeData = (SmithingRecipeData) recipe.getData();
|
||||||
ItemData output = ItemTranslator.translateToBedrock(session, recipeData.getResult());
|
ItemData output = ItemTranslator.translateToBedrock(session, recipeData.getResult());
|
||||||
for (ItemStack base : recipeData.getBase().getOptions()) {
|
for (ItemStack base : recipeData.getBase().getOptions()) {
|
||||||
ItemData bedrockBase = ItemTranslator.translateToBedrock(session, base);
|
ItemDescriptorWithCount bedrockBase = ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, base));
|
||||||
|
|
||||||
for (ItemStack addition : recipeData.getAddition().getOptions()) {
|
for (ItemStack addition : recipeData.getAddition().getOptions()) {
|
||||||
ItemData bedrockAddition = ItemTranslator.translateToBedrock(session, addition);
|
ItemDescriptorWithCount bedrockAddition = ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, addition));
|
||||||
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
|
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
|
||||||
Arrays.asList(bedrockBase, bedrockAddition),
|
List.of(bedrockBase, bedrockAddition),
|
||||||
Collections.singletonList(output), uuid, "smithing_table", 2, netId++));
|
Collections.singletonList(output), uuid, "smithing_table", 2, netId++));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,6 +179,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
// As of 1.16.4, all stonecutter recipes have one ingredient option
|
// As of 1.16.4, all stonecutter recipes have one ingredient option
|
||||||
ItemStack ingredient = stoneCuttingData.getIngredient().getOptions()[0];
|
ItemStack ingredient = stoneCuttingData.getIngredient().getOptions()[0];
|
||||||
ItemData input = ItemTranslator.translateToBedrock(session, ingredient);
|
ItemData input = ItemTranslator.translateToBedrock(session, ingredient);
|
||||||
|
ItemDescriptorWithCount descriptor = ItemDescriptorWithCount.fromItem(input);
|
||||||
ItemStack javaOutput = stoneCuttingData.getResult();
|
ItemStack javaOutput = stoneCuttingData.getResult();
|
||||||
ItemData output = ItemTranslator.translateToBedrock(session, javaOutput);
|
ItemData output = ItemTranslator.translateToBedrock(session, javaOutput);
|
||||||
if (input.equals(ItemData.AIR) || output.equals(ItemData.AIR)) {
|
if (input.equals(ItemData.AIR) || output.equals(ItemData.AIR)) {
|
||||||
|
@ -188,7 +190,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
|
|
||||||
// We need to register stonecutting recipes so they show up on Bedrock
|
// We need to register stonecutting recipes so they show up on Bedrock
|
||||||
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
|
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
|
||||||
Collections.singletonList(input), Collections.singletonList(output), uuid, "stonecutter", 0, netId));
|
Collections.singletonList(descriptor), Collections.singletonList(output), uuid, "stonecutter", 0, netId));
|
||||||
|
|
||||||
// Save the recipe list for reference when crafting
|
// Save the recipe list for reference when crafting
|
||||||
// Add the net ID as the key and the button required + output for the value
|
// Add the net ID as the key and the button required + output for the value
|
||||||
|
@ -209,19 +211,19 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
*
|
*
|
||||||
* @return the Java ingredient list as an array that Bedrock can understand
|
* @return the Java ingredient list as an array that Bedrock can understand
|
||||||
*/
|
*/
|
||||||
private ItemData[][] combinations(GeyserSession session, Ingredient[] ingredients) {
|
private ItemDescriptorWithCount[][] combinations(GeyserSession session, Ingredient[] ingredients) {
|
||||||
Map<Set<ItemData>, IntSet> squashedOptions = new HashMap<>();
|
Map<Set<ItemDescriptorWithCount>, IntSet> squashedOptions = new HashMap<>();
|
||||||
for (int i = 0; i < ingredients.length; i++) {
|
for (int i = 0; i < ingredients.length; i++) {
|
||||||
if (ingredients[i].getOptions().length == 0) {
|
if (ingredients[i].getOptions().length == 0) {
|
||||||
squashedOptions.computeIfAbsent(Collections.singleton(ItemData.AIR), k -> new IntOpenHashSet()).add(i);
|
squashedOptions.computeIfAbsent(Collections.singleton(ItemDescriptorWithCount.EMPTY), k -> new IntOpenHashSet()).add(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ingredient ingredient = ingredients[i];
|
Ingredient ingredient = ingredients[i];
|
||||||
Map<GroupedItem, List<ItemData>> groupedByIds = Arrays.stream(ingredient.getOptions())
|
Map<GroupedItem, List<ItemDescriptorWithCount>> groupedByIds = Arrays.stream(ingredient.getOptions())
|
||||||
.map(item -> ItemTranslator.translateToBedrock(session, item))
|
.map(item -> ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, item)))
|
||||||
.collect(Collectors.groupingBy(item -> new GroupedItem(item.getId(), item.getCount(), item.getTag())));
|
.collect(Collectors.groupingBy(item -> new GroupedItem(((DefaultDescriptor) item.getDescriptor()).getItemId(), item.getCount())));
|
||||||
Set<ItemData> optionSet = new HashSet<>(groupedByIds.size());
|
Set<ItemDescriptorWithCount> optionSet = new HashSet<>(groupedByIds.size());
|
||||||
for (Map.Entry<GroupedItem, List<ItemData>> entry : groupedByIds.entrySet()) {
|
for (Map.Entry<GroupedItem, List<ItemDescriptorWithCount>> entry : groupedByIds.entrySet()) {
|
||||||
if (entry.getValue().size() > 1) {
|
if (entry.getValue().size() > 1) {
|
||||||
GroupedItem groupedItem = entry.getKey();
|
GroupedItem groupedItem = entry.getKey();
|
||||||
int idCount = 0;
|
int idCount = 0;
|
||||||
|
@ -234,42 +236,38 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
if (entry.getValue().size() < idCount) {
|
if (entry.getValue().size() < idCount) {
|
||||||
optionSet.addAll(entry.getValue());
|
optionSet.addAll(entry.getValue());
|
||||||
} else {
|
} else {
|
||||||
optionSet.add(ItemData.builder()
|
optionSet.add(new ItemDescriptorWithCount(new DefaultDescriptor(groupedItem.id, Short.MAX_VALUE), groupedItem.count));
|
||||||
.id(groupedItem.id)
|
|
||||||
.damage(Short.MAX_VALUE)
|
|
||||||
.count(groupedItem.count)
|
|
||||||
.tag(groupedItem.tag).build());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ItemData item = entry.getValue().get(0);
|
ItemDescriptorWithCount item = entry.getValue().get(0);
|
||||||
optionSet.add(item);
|
optionSet.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
squashedOptions.computeIfAbsent(optionSet, k -> new IntOpenHashSet()).add(i);
|
squashedOptions.computeIfAbsent(optionSet, k -> new IntOpenHashSet()).add(i);
|
||||||
}
|
}
|
||||||
int totalCombinations = 1;
|
int totalCombinations = 1;
|
||||||
for (Set<ItemData> optionSet : squashedOptions.keySet()) {
|
for (Set<ItemDescriptorWithCount> optionSet : squashedOptions.keySet()) {
|
||||||
totalCombinations *= optionSet.size();
|
totalCombinations *= optionSet.size();
|
||||||
}
|
}
|
||||||
if (totalCombinations > 500) {
|
if (totalCombinations > 500) {
|
||||||
ItemData[] translatedItems = new ItemData[ingredients.length];
|
ItemDescriptorWithCount[] translatedItems = new ItemDescriptorWithCount[ingredients.length];
|
||||||
for (int i = 0; i < ingredients.length; i++) {
|
for (int i = 0; i < ingredients.length; i++) {
|
||||||
if (ingredients[i].getOptions().length > 0) {
|
if (ingredients[i].getOptions().length > 0) {
|
||||||
translatedItems[i] = ItemTranslator.translateToBedrock(session, ingredients[i].getOptions()[0]);
|
translatedItems[i] = ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, ingredients[i].getOptions()[0]));
|
||||||
} else {
|
} else {
|
||||||
translatedItems[i] = ItemData.AIR;
|
translatedItems[i] = ItemDescriptorWithCount.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ItemData[][]{translatedItems};
|
return new ItemDescriptorWithCount[][]{translatedItems};
|
||||||
}
|
}
|
||||||
List<Set<ItemData>> sortedSets = new ArrayList<>(squashedOptions.keySet());
|
List<Set<ItemDescriptorWithCount>> sortedSets = new ArrayList<>(squashedOptions.keySet());
|
||||||
sortedSets.sort(Comparator.comparing(Set::size, Comparator.reverseOrder()));
|
sortedSets.sort(Comparator.comparing(Set::size, Comparator.reverseOrder()));
|
||||||
ItemData[][] combinations = new ItemData[totalCombinations][ingredients.length];
|
ItemDescriptorWithCount[][] combinations = new ItemDescriptorWithCount[totalCombinations][ingredients.length];
|
||||||
int x = 1;
|
int x = 1;
|
||||||
for (Set<ItemData> set : sortedSets) {
|
for (Set<ItemDescriptorWithCount> set : sortedSets) {
|
||||||
IntSet slotSet = squashedOptions.get(set);
|
IntSet slotSet = squashedOptions.get(set);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ItemData item : set) {
|
for (ItemDescriptorWithCount item : set) {
|
||||||
for (int j = 0; j < totalCombinations / set.size(); j++) {
|
for (int j = 0; j < totalCombinations / set.size(); j++) {
|
||||||
final int comboIndex = (i * x) + (j % x) + ((j / x) * set.size() * x);
|
final int comboIndex = (i * x) + (j % x) + ((j / x) * set.size() * x);
|
||||||
for (int slot : slotSet) {
|
for (int slot : slotSet) {
|
||||||
|
@ -288,6 +286,5 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
||||||
private static class GroupedItem {
|
private static class GroupedItem {
|
||||||
int id;
|
int id;
|
||||||
int count;
|
int count;
|
||||||
NbtMap tag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.Cli
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
|
import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
|
||||||
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
@ -186,7 +187,7 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
|
||||||
uuid.toString(),
|
uuid.toString(),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
Arrays.asList(ingredients),
|
Arrays.stream(ingredients).map(ItemDescriptorWithCount::fromItem).toList(),
|
||||||
Collections.singletonList(ItemTranslator.translateToBedrock(session, item)),
|
Collections.singletonList(ItemTranslator.translateToBedrock(session, item)),
|
||||||
uuid,
|
uuid,
|
||||||
"crafting_table",
|
"crafting_table",
|
||||||
|
|
Loading…
Reference in a new issue