Large refactoring to item translator and registry/util classes

- Merged ItemTranslator and ItemStackTranslator together.
- Split ItemTranslator into two classes: ItemTranslator and ItemRegistry. The registry is where items are registered, and the translator class is where item translation takes place.
- Made most of ItemTranslator's methods static and removed the initialization in Toolbox.
- Moved a handful of registry classes previously ending with 'Utils' to a 'Registry' class to be more fitting for the term.
- Moved inventory and block entity registration out of Translators.
- Renamed Translators to PacketTranslatorRegistry.
- Yeeted Toolbox.
- Minor cleanups and small refactors.
This commit is contained in:
RednedEpic 2020-05-24 20:07:05 -05:00
parent 7154e1c816
commit 6b68bbb413
65 changed files with 980 additions and 948 deletions

View File

@ -25,6 +25,8 @@
package org.geysermc.connector; package org.geysermc.connector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.BedrockServer;
import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
@ -37,11 +39,20 @@ import org.geysermc.connector.metrics.Metrics;
import org.geysermc.connector.network.ConnectorServerEventHandler; import org.geysermc.connector.network.ConnectorServerEventHandler;
import org.geysermc.connector.network.remote.RemoteServer; import org.geysermc.connector.network.remote.RemoteServer;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.BiomeTranslator;
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry;
import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.network.translators.world.WorldManager;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.effect.EffectRegistry;
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
import org.geysermc.connector.utils.DimensionUtils; import org.geysermc.connector.utils.DimensionUtils;
import org.geysermc.connector.utils.DockerCheck; import org.geysermc.connector.utils.DockerCheck;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.LocaleUtils;
import org.geysermc.connector.network.translators.sound.SoundRegistry;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.text.DecimalFormat; import java.text.DecimalFormat;
@ -55,6 +66,8 @@ import java.util.concurrent.TimeUnit;
@Getter @Getter
public class GeyserConnector { public class GeyserConnector {
public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v390.V390_CODEC; public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v390.V390_CODEC;
public static final String NAME = "Geyser"; public static final String NAME = "Geyser";
@ -99,8 +112,19 @@ public class GeyserConnector {
logger.setDebug(config.isDebugMode()); logger.setDebug(config.isDebugMode());
Toolbox.init(); PacketTranslatorRegistry.init();
Translators.start();
/* Initialize translators and registries */
BiomeTranslator.init();
BlockTranslator.init();
BlockEntityTranslator.init();
EffectRegistry.init();
EntityIdentifierRegistry.init();
ItemRegistry.init();
ItemTranslator.init();
LocaleUtils.init();
SoundRegistry.init();
SoundHandlerRegistry.init();
if (platformType != PlatformType.STANDALONE) { if (platformType != PlatformType.STANDALONE) {
DockerCheck.check(bootstrap); DockerCheck.check(bootstrap);

View File

@ -31,7 +31,7 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.EntityData;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.utils.EffectUtils; import org.geysermc.connector.network.translators.effect.EffectRegistry;
public class AreaEffectCloudEntity extends Entity { public class AreaEffectCloudEntity extends Entity {
@ -52,7 +52,7 @@ public class AreaEffectCloudEntity extends Entity {
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue()); metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue());
} else if (entityMetadata.getId() == 10) { } else if (entityMetadata.getId() == 10) {
Particle particle = (Particle) entityMetadata.getValue(); Particle particle = (Particle) entityMetadata.getValue();
metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, EffectUtils.getParticleString(particle.getType())); metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, EffectRegistry.getParticleString(particle.getType()));
} else if (entityMetadata.getId() == 8) { } else if (entityMetadata.getId() == 8) {
metadata.put(EntityData.POTION_COLOR, entityMetadata.getValue()); metadata.put(EntityData.POTION_COLOR, entityMetadata.getValue());
} }

View File

@ -51,8 +51,7 @@ import org.geysermc.connector.entity.attribute.AttributeType;
import org.geysermc.connector.entity.living.ArmorStandEntity; import org.geysermc.connector.entity.living.ArmorStandEntity;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.AttributeUtils;
import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.ChunkUtils;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;
@ -225,11 +224,11 @@ public class Entity {
// Shield code // Shield code
if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) { if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) {
if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) || if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemRegistry.SHIELD) ||
(session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).getId() == ItemTranslator.SHIELD)) { (session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).getId() == ItemRegistry.SHIELD)) {
ClientPlayerUseItemPacket useItemPacket; ClientPlayerUseItemPacket useItemPacket;
metadata.getFlags().setFlag(EntityFlag.BLOCKING, true); metadata.getFlags().setFlag(EntityFlag.BLOCKING, true);
if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) { if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemRegistry.SHIELD) {
useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
} }
// Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent // Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent

View File

@ -31,7 +31,7 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket; import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemTranslator;
public class ItemEntity extends Entity { public class ItemEntity extends Entity {
@ -49,7 +49,7 @@ public class ItemEntity extends Entity {
itemPacket.setUniqueEntityId(geyserId); itemPacket.setUniqueEntityId(geyserId);
itemPacket.setFromFishing(false); itemPacket.setFromFishing(false);
itemPacket.getMetadata().putAll(metadata); itemPacket.getMetadata().putAll(metadata);
itemPacket.setItemInHand(Translators.getItemTranslator().translateToBedrock(session, (ItemStack) entityMetadata.getValue())); itemPacket.setItemInHand(ItemTranslator.translateToBedrock((ItemStack) entityMetadata.getValue()));
session.sendUpstreamPacket(itemPacket); session.sendUpstreamPacket(itemPacket);
} }

View File

@ -38,10 +38,10 @@ import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.Toolbox;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -98,12 +98,12 @@ public class ItemFrameEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) { if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) {
ItemData itemData = Translators.getItemTranslator().translateToBedrock(session, (ItemStack) entityMetadata.getValue()); ItemData itemData = ItemTranslator.translateToBedrock((ItemStack) entityMetadata.getValue());
ItemEntry itemEntry = Translators.getItemTranslator().getItem((ItemStack) entityMetadata.getValue()); ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
CompoundTagBuilder builder = CompoundTag.builder(); CompoundTagBuilder builder = CompoundTag.builder();
String blockName = ""; String blockName = "";
for (StartGamePacket.ItemEntry startGamePacketItemEntry: Toolbox.ITEMS) { for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
if (startGamePacketItemEntry.getId() == (short) itemEntry.getBedrockId()) { if (startGamePacketItemEntry.getId() == (short) itemEntry.getBedrockId()) {
blockName = startGamePacketItemEntry.getIdentifier(); blockName = startGamePacketItemEntry.getIdentifier();
break; break;

View File

@ -31,7 +31,7 @@ import org.geysermc.common.AuthType;
import org.geysermc.connector.GeyserConfiguration; import org.geysermc.connector.GeyserConfiguration;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
import org.geysermc.connector.utils.LoginEncryptionUtils; import org.geysermc.connector.utils.LoginEncryptionUtils;
public class UpstreamPacketHandler extends LoggingPacketHandler { public class UpstreamPacketHandler extends LoggingPacketHandler {
@ -41,7 +41,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
} }
private boolean translateAndDefault(BedrockPacket packet) { private boolean translateAndDefault(BedrockPacket packet) {
return Registry.BEDROCK.translate(packet.getClass(), packet, session); return PacketTranslatorRegistry.BEDROCK_TRANSLATOR.translate(packet.getClass(), packet, session);
} }
@Override @Override

View File

@ -65,12 +65,14 @@ import org.geysermc.connector.network.remote.RemoteServer;
import org.geysermc.connector.network.session.auth.AuthData; 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.session.cache.*; import org.geysermc.connector.network.session.cache.*;
import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.BiomeTranslator;
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.ChunkUtils;
import org.geysermc.connector.utils.LocaleUtils; import org.geysermc.connector.utils.LocaleUtils;
import org.geysermc.connector.utils.SkinUtils; import org.geysermc.connector.utils.SkinUtils;
import org.geysermc.connector.utils.Toolbox;
import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.BedrockData;
import org.geysermc.floodgate.util.EncryptionUtil; import org.geysermc.floodgate.util.EncryptionUtil;
@ -194,16 +196,16 @@ public class GeyserSession implements CommandSender {
ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket(); BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
biomeDefinitionListPacket.setTag(Toolbox.BIOMES); biomeDefinitionListPacket.setTag(BiomeTranslator.BIOMES);
upstream.sendPacket(biomeDefinitionListPacket); upstream.sendPacket(biomeDefinitionListPacket);
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket(); AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
entityPacket.setTag(Toolbox.ENTITY_IDENTIFIERS); entityPacket.setTag(EntityIdentifierRegistry.ENTITY_IDENTIFIERS);
upstream.sendPacket(entityPacket); upstream.sendPacket(entityPacket);
InventoryContentPacket creativePacket = new InventoryContentPacket(); InventoryContentPacket creativePacket = new InventoryContentPacket();
creativePacket.setContainerId(ContainerId.CREATIVE); creativePacket.setContainerId(ContainerId.CREATIVE);
creativePacket.setContents(Toolbox.CREATIVE_ITEMS); creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS);
upstream.sendPacket(creativePacket); upstream.sendPacket(creativePacket);
PlayStatusPacket playStatusPacket = new PlayStatusPacket(); PlayStatusPacket playStatusPacket = new PlayStatusPacket();
@ -345,7 +347,7 @@ public class GeyserSession implements CommandSender {
lastDimPacket = event.getPacket(); lastDimPacket = event.getPacket();
return; return;
} else if (lastDimPacket != null) { } else if (lastDimPacket != null) {
Registry.JAVA.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this); PacketTranslatorRegistry.JAVA_TRANSLATOR.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this);
lastDimPacket = null; lastDimPacket = null;
} }
@ -361,7 +363,7 @@ public class GeyserSession implements CommandSender {
} }
} }
Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); PacketTranslatorRegistry.JAVA_TRANSLATOR.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this);
} }
} }
}); });
@ -497,7 +499,7 @@ public class GeyserSession implements CommandSender {
startGamePacket.setEnchantmentSeed(0); startGamePacket.setEnchantmentSeed(0);
startGamePacket.setMultiplayerCorrelationId(""); startGamePacket.setMultiplayerCorrelationId("");
startGamePacket.setBlockPalette(BlockTranslator.BLOCKS); startGamePacket.setBlockPalette(BlockTranslator.BLOCKS);
startGamePacket.setItemEntries(Toolbox.ITEMS); startGamePacket.setItemEntries(ItemRegistry.ITEMS);
startGamePacket.setVanillaVersion("*"); startGamePacket.setVanillaVersion("*");
// startGamePacket.setMovementServerAuthoritative(true); // startGamePacket.setMovementServerAuthoritative(true);
upstream.sendPacket(startGamePacket); upstream.sendPacket(startGamePacket);

View File

@ -1,14 +1,72 @@
/*
* 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/Geyser
*
*/
package org.geysermc.connector.network.translators; package org.geysermc.connector.network.translators;
import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.nbt.stream.NBTInputStream;
import com.nukkitx.nbt.tag.CompoundTag;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.FileUtils;
import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
//Based off of ProtocolSupport's LegacyBiomeData.java https://github.com/ProtocolSupport/ProtocolSupport/blob/b2cad35977f3fcb65bee57b9e14fc9c975f71d32/src/protocolsupport/protocol/typeremapper/legacy/LegacyBiomeData.java // Based off of ProtocolSupport's LegacyBiomeData.java:
//Array index formula by https://wiki.vg/Chunk_Format // https://github.com/ProtocolSupport/ProtocolSupport/blob/b2cad35977f3fcb65bee57b9e14fc9c975f71d32/src/protocolsupport/protocol/typeremapper/legacy/LegacyBiomeData.java
// Array index formula by https://wiki.vg/Chunk_Format
public class BiomeTranslator { public class BiomeTranslator {
public static final CompoundTag BIOMES;
private BiomeTranslator() {
}
public static void init() {
// no-op
}
static {
/* Load biomes */
InputStream stream = FileUtils.getResource("bedrock/biome_definitions.dat");
CompoundTag biomesTag;
try (NBTInputStream biomenbtInputStream = NbtUtils.createNetworkReader(stream)){
biomesTag = (CompoundTag) biomenbtInputStream.readTag();
BIOMES = biomesTag;
} catch (Exception ex) {
GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?");
throw new AssertionError(ex);
}
}
public static byte[] toBedrockBiome(int[] biomeData) { public static byte[] toBedrockBiome(int[] biomeData) {
byte[] bedrockData = new byte[256]; byte[] bedrockData = new byte[256];
if(biomeData == null) { if (biomeData == null) {
return bedrockData; return bedrockData;
} }
@ -24,12 +82,12 @@ public class BiomeTranslator {
return bedrockData; return bedrockData;
} }
protected static void fillArray(int z, int x, byte[] legacyBiomeData, int biomeId) { private static void fillArray(int z, int x, byte[] legacyBiomeData, int biomeId) {
int offset = (z << 4) | x; int offset = (z << 4) | x;
Arrays.fill(legacyBiomeData, offset, offset + 4, (byte) biomeId); Arrays.fill(legacyBiomeData, offset, offset + 4, (byte) biomeId);
} }
protected static byte biomeID(int[] biomeData, int x, int z) { private static byte biomeID(int[] biomeData, int x, int z) {
return (byte) biomeData[((z >> 2) & 3) << 2 | ((x >> 2) & 3)]; return (byte) biomeData[((z >> 2) & 3) << 2 | ((x >> 2) & 3)];
} }
} }

View File

@ -0,0 +1,60 @@
/*
* 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/Geyser
*
*/
package org.geysermc.connector.network.translators;
import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.nbt.stream.NBTInputStream;
import com.nukkitx.nbt.tag.CompoundTag;
import org.geysermc.connector.utils.FileUtils;
import java.io.InputStream;
/**
* Registry for entity identifiers.
*/
public class EntityIdentifierRegistry {
public static CompoundTag ENTITY_IDENTIFIERS;
private EntityIdentifierRegistry() {
}
public static void init() {
// no-op
}
static {
/* Load entity identifiers */
InputStream stream = FileUtils.getResource("bedrock/entity_identifiers.dat");
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) {
ENTITY_IDENTIFIERS = (CompoundTag) nbtInputStream.readTag();
} catch (Exception e) {
throw new AssertionError("Unable to get entities from entity identifiers", e);
}
}
}

View File

@ -1,250 +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/Geyser
*/
package org.geysermc.connector.network.translators;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.nbt.tag.Tag;
import com.nukkitx.protocol.bedrock.data.ItemData;
import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.MessageUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class ItemStackTranslator {
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack == null) {
return ItemData.AIR;
}
if (itemStack.getNbt() == null) {
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount());
}
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt()));
}
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
if (itemData == null) return null;
if (itemData.getTag() == null) {
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), new com.github.steveice10.opennbt.tag.builtin.CompoundTag(""));
}
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT(itemData.getTag()));
}
public abstract List<ItemEntry> getAppliedItems();
public CompoundTag translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) {
Map<String, Tag<?>> javaValue = new HashMap<String, Tag<?>>();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = tag.get(str);
com.nukkitx.nbt.tag.Tag translatedTag = translateToBedrockNBT(javaTag);
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
com.nukkitx.nbt.tag.CompoundTag bedrockTag = new com.nukkitx.nbt.tag.CompoundTag(tag.getName(), javaValue);
return bedrockTag;
}
private com.nukkitx.nbt.tag.Tag translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) {
if (tag instanceof ByteArrayTag) {
ByteArrayTag byteArrayTag = (ByteArrayTag) tag;
return new com.nukkitx.nbt.tag.ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof ByteTag) {
ByteTag byteTag = (ByteTag) tag;
return new com.nukkitx.nbt.tag.ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof DoubleTag) {
DoubleTag doubleTag = (DoubleTag) tag;
return new com.nukkitx.nbt.tag.DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof FloatTag) {
FloatTag floatTag = (FloatTag) tag;
return new com.nukkitx.nbt.tag.FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof IntArrayTag) {
IntArrayTag intArrayTag = (IntArrayTag) tag;
return new com.nukkitx.nbt.tag.IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof IntTag) {
IntTag intTag = (IntTag) tag;
return new com.nukkitx.nbt.tag.IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof LongArrayTag) {
LongArrayTag longArrayTag = (LongArrayTag) tag;
return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof LongTag) {
LongTag longTag = (LongTag) tag;
return new com.nukkitx.nbt.tag.LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof ShortTag) {
ShortTag shortTag = (ShortTag) tag;
return new com.nukkitx.nbt.tag.ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof StringTag) {
StringTag stringTag = (StringTag) tag;
return new com.nukkitx.nbt.tag.StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
List<Tag> tagList = new ArrayList<>();
for (com.github.steveice10.opennbt.tag.builtin.Tag value : listTag) {
tagList.add(translateToBedrockNBT(value));
}
Class clazz = CompoundTag.class;
if (!tagList.isEmpty()) {
clazz = tagList.get(0).getClass();
}
return new com.nukkitx.nbt.tag.ListTag(listTag.getName(), clazz, tagList);
}
if (tag instanceof com.github.steveice10.opennbt.tag.builtin.CompoundTag) {
com.github.steveice10.opennbt.tag.builtin.CompoundTag compoundTag = (com.github.steveice10.opennbt.tag.builtin.CompoundTag) tag;
return translateNbtToBedrock(compoundTag);
}
return null;
}
public com.github.steveice10.opennbt.tag.builtin.CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) {
com.github.steveice10.opennbt.tag.builtin.CompoundTag javaTag = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(tag.getName());
Map<String, com.github.steveice10.opennbt.tag.builtin.Tag> javaValue = javaTag.getValue();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
com.nukkitx.nbt.tag.Tag bedrockTag = tag.get(str);
com.github.steveice10.opennbt.tag.builtin.Tag translatedTag = translateToJavaNBT(bedrockTag);
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
javaTag.setValue(javaValue);
return javaTag;
}
private com.github.steveice10.opennbt.tag.builtin.Tag translateToJavaNBT(com.nukkitx.nbt.tag.Tag tag) {
if (tag instanceof com.nukkitx.nbt.tag.ByteArrayTag) {
com.nukkitx.nbt.tag.ByteArrayTag byteArrayTag = (com.nukkitx.nbt.tag.ByteArrayTag) tag;
return new ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ByteTag) {
com.nukkitx.nbt.tag.ByteTag byteTag = (com.nukkitx.nbt.tag.ByteTag) tag;
return new ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.DoubleTag) {
com.nukkitx.nbt.tag.DoubleTag doubleTag = (com.nukkitx.nbt.tag.DoubleTag) tag;
return new DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.FloatTag) {
com.nukkitx.nbt.tag.FloatTag floatTag = (com.nukkitx.nbt.tag.FloatTag) tag;
return new FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntArrayTag) {
com.nukkitx.nbt.tag.IntArrayTag intArrayTag = (com.nukkitx.nbt.tag.IntArrayTag) tag;
return new IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntTag) {
com.nukkitx.nbt.tag.IntTag intTag = (com.nukkitx.nbt.tag.IntTag) tag;
return new IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongArrayTag) {
com.nukkitx.nbt.tag.LongArrayTag longArrayTag = (com.nukkitx.nbt.tag.LongArrayTag) tag;
return new LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongTag) {
com.nukkitx.nbt.tag.LongTag longTag = (com.nukkitx.nbt.tag.LongTag) tag;
return new LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ShortTag) {
com.nukkitx.nbt.tag.ShortTag shortTag = (com.nukkitx.nbt.tag.ShortTag) tag;
return new ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.StringTag) {
com.nukkitx.nbt.tag.StringTag stringTag = (com.nukkitx.nbt.tag.StringTag) tag;
return new StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ListTag) {
com.nukkitx.nbt.tag.ListTag listTag = (com.nukkitx.nbt.tag.ListTag) tag;
List<com.github.steveice10.opennbt.tag.builtin.Tag> tags = new ArrayList<>();
for (Object value : listTag.getValue()) {
if (!(value instanceof com.nukkitx.nbt.tag.Tag))
continue;
com.nukkitx.nbt.tag.Tag tagValue = (com.nukkitx.nbt.tag.Tag) value;
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = translateToJavaNBT(tagValue);
if (javaTag != null)
tags.add(javaTag);
}
return new ListTag(listTag.getName(), tags);
}
if (tag instanceof com.nukkitx.nbt.tag.CompoundTag) {
com.nukkitx.nbt.tag.CompoundTag compoundTag = (com.nukkitx.nbt.tag.CompoundTag) tag;
return translateToJavaNBT(compoundTag);
}
return null;
}
}

View File

@ -1,45 +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/Geyser
*/
package org.geysermc.connector.network.translators;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.geysermc.connector.network.translators.item.ItemEntry;
public class NbtItemStackTranslator {
public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) {
}
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
}
public boolean acceptItem(ItemEntry itemEntry) {
return true;
}
}

View File

@ -35,33 +35,59 @@ import org.geysermc.connector.network.session.GeyserSession;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockPacket;
import org.reflections.Reflections;
public class Registry<T> { public class PacketTranslatorRegistry<T> {
private final Map<Class<? extends T>, PacketTranslator<? extends T>> MAP = new HashMap<>(); private final Map<Class<? extends T>, PacketTranslator<? extends T>> translators = new HashMap<>();
public static final Registry<Packet> JAVA = new Registry<>(); public static final PacketTranslatorRegistry<Packet> JAVA_TRANSLATOR = new PacketTranslatorRegistry<>();
public static final Registry<BedrockPacket> BEDROCK = new Registry<>(); public static final PacketTranslatorRegistry<BedrockPacket> BEDROCK_TRANSLATOR = new PacketTranslatorRegistry<>();
private static final ObjectArrayList<Class<?>> IGNORED_PACKETS = new ObjectArrayList<>(); private static final ObjectArrayList<Class<?>> IGNORED_PACKETS = new ObjectArrayList<>();
static { static {
Reflections ref = new Reflections("org.geysermc.connector.network.translators");
for (Class<?> clazz : ref.getTypesAnnotatedWith(Translator.class)) {
Class<?> packet = clazz.getAnnotation(Translator.class).packet();
GeyserConnector.getInstance().getLogger().debug("Found annotated translator: " + clazz.getCanonicalName() + " : " + packet.getSimpleName());
try {
if (Packet.class.isAssignableFrom(packet)) {
Class<? extends Packet> targetPacket = (Class<? extends Packet>) packet;
PacketTranslator<? extends Packet> translator = (PacketTranslator<? extends Packet>) clazz.newInstance();
JAVA_TRANSLATOR.translators.put(targetPacket, translator);
} else if (BedrockPacket.class.isAssignableFrom(packet)) {
Class<? extends BedrockPacket> targetPacket = (Class<? extends BedrockPacket>) packet;
PacketTranslator<? extends BedrockPacket> translator = (PacketTranslator<? extends BedrockPacket>) clazz.newInstance();
BEDROCK_TRANSLATOR.translators.put(targetPacket, translator);
} else {
GeyserConnector.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet.");
}
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated translator " + clazz.getCanonicalName() + ".");
}
}
IGNORED_PACKETS.add(ServerUpdateLightPacket.class); IGNORED_PACKETS.add(ServerUpdateLightPacket.class);
} }
public static void registerJava(Class<? extends Packet> targetPacket, PacketTranslator<? extends Packet> translator) { private PacketTranslatorRegistry() {
JAVA.MAP.put(targetPacket, translator);
} }
public static void registerBedrock(Class<? extends BedrockPacket> targetPacket, PacketTranslator<? extends BedrockPacket> translator) { public static void init() {
BEDROCK.MAP.put(targetPacket, translator); // no-op
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <P extends T> boolean translate(Class<? extends P> clazz, P packet, GeyserSession session) { public <P extends T> boolean translate(Class<? extends P> clazz, P packet, GeyserSession session) {
if (!session.getUpstream().isClosed() && !session.isClosed()) { if (!session.getUpstream().isClosed() && !session.isClosed()) {
try { try {
if (MAP.containsKey(clazz)) { if (translators.containsKey(clazz)) {
((PacketTranslator<P>) MAP.get(clazz)).translate(packet, session); ((PacketTranslator<P>) translators.get(clazz)).translate(packet, session);
return true; return true;
} else { } else {
if (!IGNORED_PACKETS.contains(clazz)) if (!IGNORED_PACKETS.contains(clazz))

View File

@ -1,175 +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/Geyser
*/
package org.geysermc.connector.network.translators;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import com.nukkitx.protocol.bedrock.data.ContainerType;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.world.block.entity.*;
import org.geysermc.connector.network.translators.inventory.*;
import org.geysermc.connector.network.translators.inventory.updater.ContainerInventoryUpdater;
import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.reflections.Reflections;
import com.github.steveice10.packetlib.packet.Packet;
import com.nukkitx.nbt.CompoundTagBuilder;
import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.nbt.stream.NBTOutputStream;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.protocol.bedrock.BedrockPacket;
import lombok.Getter;
public class Translators {
@Getter
private static ItemTranslator itemTranslator;
@Getter
private static Map<WindowType, InventoryTranslator> inventoryTranslators = new HashMap<>();
@Getter
private static Map<String, BlockEntityTranslator> blockEntityTranslators = new HashMap<>();
@Getter
private static ObjectArrayList<RequiresBlockState> requiresBlockStateMap = new ObjectArrayList<>();
private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag();
public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
static {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
try (NBTOutputStream stream = NbtUtils.createNetworkWriter(outputStream)) {
stream.write(EMPTY_TAG);
}
EMPTY_LEVEL_CHUNK_DATA = outputStream.toByteArray();
}catch (IOException e) {
throw new AssertionError("Unable to generate empty level chunk data");
}
}
@SuppressWarnings("unchecked")
public static void start() {
Reflections ref = new Reflections("org.geysermc.connector.network.translators");
for (Class<?> clazz : ref.getTypesAnnotatedWith(Translator.class)) {
Class<?> packet = clazz.getAnnotation(Translator.class).packet();
GeyserConnector.getInstance().getLogger().debug("Found annotated translator: " + clazz.getCanonicalName() + " : " + packet.getSimpleName());
try {
if (Packet.class.isAssignableFrom(packet)) {
Class<? extends Packet> targetPacket = (Class<? extends Packet>) packet;
PacketTranslator<? extends Packet> translator = (PacketTranslator<? extends Packet>) clazz.newInstance();
Registry.registerJava(targetPacket, translator);
} else if (BedrockPacket.class.isAssignableFrom(packet)) {
Class<? extends BedrockPacket> targetPacket = (Class<? extends BedrockPacket>) packet;
PacketTranslator<? extends BedrockPacket> translator = (PacketTranslator<? extends BedrockPacket>) clazz.newInstance();
Registry.registerBedrock(targetPacket, translator);
} else {
GeyserConnector.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet.");
}
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated translator " + clazz.getCanonicalName() + ".");
}
}
itemTranslator = new ItemTranslator();
itemTranslator.init();
BlockTranslator.init();
registerBlockEntityTranslators();
registerInventoryTranslators();
}
private static void registerBlockEntityTranslators() {
Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity");
for (Class<?> clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) {
GeyserConnector.getInstance().getLogger().debug("Found annotated block entity: " + clazz.getCanonicalName());
try {
blockEntityTranslators.put(clazz.getAnnotation(BlockEntity.class).name(), (BlockEntityTranslator) clazz.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated block entity " + clazz.getCanonicalName() + ".");
}
}
for (Class<?> clazz : ref.getSubTypesOf(RequiresBlockState.class)) {
GeyserConnector.getInstance().getLogger().debug("Found block entity that requires block state: " + clazz.getCanonicalName());
try {
requiresBlockStateMap.add((RequiresBlockState) clazz.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate required block state " + clazz.getCanonicalName() + ".");
}
}
}
private static void registerInventoryTranslators() {
inventoryTranslators.put(null, new PlayerInventoryTranslator()); //player inventory
inventoryTranslators.put(WindowType.GENERIC_9X1, new SingleChestInventoryTranslator(9));
inventoryTranslators.put(WindowType.GENERIC_9X2, new SingleChestInventoryTranslator(18));
inventoryTranslators.put(WindowType.GENERIC_9X3, new SingleChestInventoryTranslator(27));
inventoryTranslators.put(WindowType.GENERIC_9X4, new DoubleChestInventoryTranslator(36));
inventoryTranslators.put(WindowType.GENERIC_9X5, new DoubleChestInventoryTranslator(45));
inventoryTranslators.put(WindowType.GENERIC_9X6, new DoubleChestInventoryTranslator(54));
inventoryTranslators.put(WindowType.BREWING_STAND, new BrewingInventoryTranslator());
inventoryTranslators.put(WindowType.ANVIL, new AnvilInventoryTranslator());
inventoryTranslators.put(WindowType.CRAFTING, new CraftingInventoryTranslator());
inventoryTranslators.put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator());
//inventoryTranslators.put(WindowType.ENCHANTMENT, new EnchantmentInventoryTranslator()); //TODO
InventoryTranslator furnace = new FurnaceInventoryTranslator();
inventoryTranslators.put(WindowType.FURNACE, furnace);
inventoryTranslators.put(WindowType.BLAST_FURNACE, furnace);
inventoryTranslators.put(WindowType.SMOKER, furnace);
InventoryUpdater containerUpdater = new ContainerInventoryUpdater();
inventoryTranslators.put(WindowType.GENERIC_3X3, new BlockInventoryTranslator(9, "minecraft:dispenser[facing=north,triggered=false]", ContainerType.DISPENSER, containerUpdater));
inventoryTranslators.put(WindowType.HOPPER, new BlockInventoryTranslator(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER, containerUpdater));
inventoryTranslators.put(WindowType.SHULKER_BOX, new BlockInventoryTranslator(27, "minecraft:shulker_box[facing=north]", ContainerType.CONTAINER, containerUpdater));
//inventoryTranslators.put(WindowType.BEACON, new BlockInventoryTranslator(1, "minecraft:beacon", ContainerType.BEACON)); //TODO
}
}

View File

@ -31,15 +31,13 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientMoveI
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.packet.BlockPickRequestPacket; import com.nukkitx.protocol.bedrock.packet.BlockPickRequestPacket;
import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket; import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket;
import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.Translators;
@Translator(packet = BlockPickRequestPacket.class) @Translator(packet = BlockPickRequestPacket.class)
public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator<BlockPickRequestPacket> { public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator<BlockPickRequestPacket> {
@ -61,14 +59,13 @@ public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator<Bl
} }
String targetIdentifier = BlockTranslator.getJavaIdBlockMap().inverse().get(blockToPick).split("\\[")[0]; String targetIdentifier = BlockTranslator.getJavaIdBlockMap().inverse().get(blockToPick).split("\\[")[0];
ItemTranslator itemTranslator = Translators.getItemTranslator();
// Check hotbar for item // Check hotbar for item
for (int i = 36; i < 45; i++) { for (int i = 36; i < 45; i++) {
if (inventory.getItem(i) == null) { if (inventory.getItem(i) == null) {
continue; continue;
} }
ItemEntry item = itemTranslator.getItem(inventory.getItem(i)); ItemEntry item = ItemRegistry.getItem(inventory.getItem(i));
// If this isn't the item we're looking for // If this isn't the item we're looking for
if (!item.getJavaIdentifier().equals(targetIdentifier)) { if (!item.getJavaIdentifier().equals(targetIdentifier)) {
continue; continue;
@ -90,7 +87,7 @@ public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator<Bl
if (inventory.getItem(i) == null) { if (inventory.getItem(i) == null) {
continue; continue;
} }
ItemEntry item = itemTranslator.getItem(inventory.getItem(i)); ItemEntry item = ItemRegistry.getItem(inventory.getItem(i));
// If this isn't the item we're looking for // If this isn't the item we're looking for
if (!item.getJavaIdentifier().equals(targetIdentifier)) { if (!item.getJavaIdentifier().equals(targetIdentifier)) {
continue; continue;

View File

@ -38,7 +38,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket;
import com.nukkitx.protocol.bedrock.packet.InteractPacket; import com.nukkitx.protocol.bedrock.packet.InteractPacket;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemRegistry;
@Translator(packet = InteractPacket.class) @Translator(packet = InteractPacket.class)
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> { public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
@ -51,7 +51,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
switch (packet.getAction()) { switch (packet.getAction()) {
case INTERACT: case INTERACT:
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) { if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemRegistry.SHIELD) {
break; break;
} }
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),

View File

@ -49,9 +49,9 @@ import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler; import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
@ -65,12 +65,12 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
case NORMAL: case NORMAL:
Inventory inventory = session.getInventoryCache().getOpenInventory(); Inventory inventory = session.getInventoryCache().getOpenInventory();
if (inventory == null) inventory = session.getInventory(); if (inventory == null) inventory = session.getInventory();
Translators.getInventoryTranslators().get(inventory.getWindowType()).translateActions(session, inventory, packet.getActions()); InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType()).translateActions(session, inventory, packet.getActions());
break; break;
case INVENTORY_MISMATCH: case INVENTORY_MISMATCH:
Inventory inv = session.getInventoryCache().getOpenInventory(); Inventory inv = session.getInventoryCache().getOpenInventory();
if (inv == null) inv = session.getInventory(); if (inv == null) inv = session.getInventory();
Translators.getInventoryTranslators().get(inv.getWindowType()).updateInventory(session, inv); InventoryTranslator.INVENTORY_TRANSLATORS.get(inv.getWindowType()).updateInventory(session, inv);
InventoryUtils.updateCursor(session); InventoryUtils.updateCursor(session);
break; break;
case ITEM_USE: case ITEM_USE:
@ -99,7 +99,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
session.sendDownstreamPacket(blockPacket); session.sendDownstreamPacket(blockPacket);
// Otherwise boats will not be able to be placed in survival // Otherwise boats will not be able to be placed in survival
if (packet.getItemInHand() != null && packet.getItemInHand().getId() == ItemTranslator.BOAT) { if (packet.getItemInHand() != null && packet.getItemInHand().getId() == ItemRegistry.BOAT) {
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.sendDownstreamPacket(itemPacket); session.sendDownstreamPacket(itemPacket);
} }
@ -126,7 +126,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
blockPos = blockPos.add(1, 0, 0); blockPos = blockPos.add(1, 0, 0);
break; break;
} }
ItemEntry handItem = Translators.getItemTranslator().getItem(packet.getItemInHand()); ItemEntry handItem = ItemRegistry.getItem(packet.getItemInHand());
if (handItem.isBlock()) { if (handItem.isBlock()) {
session.setLastBlockPlacePosition(blockPos); session.setLastBlockPlacePosition(blockPos);
session.setLastBlockPlacedId(handItem.getJavaIdentifier()); session.setLastBlockPlacedId(handItem.getJavaIdentifier());
@ -136,7 +136,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
break; break;
case 1: case 1:
ItemStack shieldSlot = session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36); ItemStack shieldSlot = session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36);
if (shieldSlot != null && shieldSlot.getId() == ItemTranslator.SHIELD) { if (shieldSlot != null && shieldSlot.getId() == ItemRegistry.SHIELD) {
break; break;
} // Handled in Entity.java } // Handled in Entity.java
ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);

View File

@ -1,49 +1,50 @@
/* /*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* *
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.connector.utils; package org.geysermc.connector.network.translators.effect;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleType; import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleType;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.data.SoundEvent;
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 lombok.NonNull; import lombok.NonNull;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.effect.Effect; import org.geysermc.connector.utils.FileUtils;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
public class EffectUtils { /**
* Registry for particles and effects.
*/
public class EffectRegistry {
public static final Map<String, Effect> EFFECTS = new HashMap<>(); public static final Map<String, Effect> EFFECTS = new HashMap<>();
public static final Int2ObjectMap<SoundEvent> RECORDS = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap<SoundEvent> RECORDS = new Int2ObjectOpenHashMap<>();
@ -57,10 +58,10 @@ public class EffectUtils {
static { static {
/* Load particles */ /* Load particles */
InputStream particleStream = Toolbox.getResource("mappings/particles.json"); InputStream particleStream = FileUtils.getResource("mappings/particles.json");
JsonNode particleEntries; JsonNode particleEntries;
try { try {
particleEntries = Toolbox.JSON_MAPPER.readTree(particleStream); particleEntries = GeyserConnector.JSON_MAPPER.readTree(particleStream);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load particle map", e); throw new AssertionError("Unable to load particle map", e);
} }
@ -69,10 +70,10 @@ public class EffectUtils {
while (particlesIterator.hasNext()) { while (particlesIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = particlesIterator.next(); Map.Entry<String, JsonNode> entry = particlesIterator.next();
try { try {
setIdentifier(ParticleType.valueOf(entry.getKey().toUpperCase()), LevelEventType.valueOf(entry.getValue().asText().toUpperCase())); particleTypeMap.put(ParticleType.valueOf(entry.getKey().toUpperCase()), LevelEventType.valueOf(entry.getValue().asText().toUpperCase()));
} catch (IllegalArgumentException e1) { } catch (IllegalArgumentException e1) {
try { try {
setIdentifier(ParticleType.valueOf(entry.getKey().toUpperCase()), entry.getValue().asText()); particleStringMap.put(ParticleType.valueOf(entry.getKey().toUpperCase()), entry.getValue().asText());
GeyserConnector.getInstance().getLogger().debug("Force to map particle " GeyserConnector.getInstance().getLogger().debug("Force to map particle "
+ entry.getKey() + entry.getKey()
+ "=>" + "=>"
@ -85,10 +86,10 @@ public class EffectUtils {
} }
/* Load effects */ /* Load effects */
InputStream effectsStream = Toolbox.getResource("mappings/effects.json"); InputStream effectsStream = FileUtils.getResource("mappings/effects.json");
JsonNode effects; JsonNode effects;
try { try {
effects = Toolbox.JSON_MAPPER.readTree(effectsStream); effects = GeyserConnector.JSON_MAPPER.readTree(effectsStream);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load effects mappings", e); throw new AssertionError("Unable to load effects mappings", e);
} }
@ -112,14 +113,6 @@ public class EffectUtils {
} }
} }
public static void setIdentifier(ParticleType type, LevelEventType identifier) {
particleTypeMap.put(type, identifier);
}
public static void setIdentifier(ParticleType type, String identifier) {
particleStringMap.put(type, identifier);
}
public static LevelEventType getParticleLevelEventType(@NonNull ParticleType type) { public static LevelEventType getParticleLevelEventType(@NonNull ParticleType type) {
return particleTypeMap.getOrDefault(type, null); return particleTypeMap.getOrDefault(type, null);
} }
@ -127,5 +120,4 @@ public class EffectUtils {
public static String getParticleString(@NonNull ParticleType type){ public static String getParticleString(@NonNull ParticleType type){
return particleStringMap.getOrDefault(type, null); return particleStringMap.getOrDefault(type, null);
} }
} }

View File

@ -25,15 +25,50 @@
package org.geysermc.connector.network.translators.inventory; package org.geysermc.connector.network.translators.inventory;
import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import com.nukkitx.protocol.bedrock.data.ContainerType;
import com.nukkitx.protocol.bedrock.data.InventoryActionData; import com.nukkitx.protocol.bedrock.data.InventoryActionData;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.inventory.updater.ContainerInventoryUpdater;
import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@AllArgsConstructor @AllArgsConstructor
public abstract class InventoryTranslator { public abstract class InventoryTranslator {
public static final Map<WindowType, InventoryTranslator> INVENTORY_TRANSLATORS = new HashMap<WindowType, InventoryTranslator>() {
{
put(null, new PlayerInventoryTranslator()); //player inventory
put(WindowType.GENERIC_9X1, new SingleChestInventoryTranslator(9));
put(WindowType.GENERIC_9X2, new SingleChestInventoryTranslator(18));
put(WindowType.GENERIC_9X3, new SingleChestInventoryTranslator(27));
put(WindowType.GENERIC_9X4, new DoubleChestInventoryTranslator(36));
put(WindowType.GENERIC_9X5, new DoubleChestInventoryTranslator(45));
put(WindowType.GENERIC_9X6, new DoubleChestInventoryTranslator(54));
put(WindowType.BREWING_STAND, new BrewingInventoryTranslator());
put(WindowType.ANVIL, new AnvilInventoryTranslator());
put(WindowType.CRAFTING, new CraftingInventoryTranslator());
put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator());
//put(WindowType.ENCHANTMENT, new EnchantmentInventoryTranslator()); //TODO
InventoryTranslator furnace = new FurnaceInventoryTranslator();
put(WindowType.FURNACE, furnace);
put(WindowType.BLAST_FURNACE, furnace);
put(WindowType.SMOKER, furnace);
InventoryUpdater containerUpdater = new ContainerInventoryUpdater();
put(WindowType.GENERIC_3X3, new BlockInventoryTranslator(9, "minecraft:dispenser[facing=north,triggered=false]", ContainerType.DISPENSER, containerUpdater));
put(WindowType.HOPPER, new BlockInventoryTranslator(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER, containerUpdater));
put(WindowType.SHULKER_BOX, new BlockInventoryTranslator(27, "minecraft:shulker_box[facing=north]", ContainerType.CONTAINER, containerUpdater));
//put(WindowType.BEACON, new BlockInventoryTranslator(1, "minecraft:beacon", ContainerType.BEACON)); //TODO
}
};
public final int size; public final int size;
public abstract void prepareInventory(GeyserSession session, Inventory inventory); public abstract void prepareInventory(GeyserSession session, Inventory inventory);

View File

@ -36,10 +36,9 @@ import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator; import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
import org.geysermc.connector.utils.Toolbox;
import java.util.List; import java.util.List;
@ -60,11 +59,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
ItemData[] contents = new ItemData[36]; ItemData[] contents = new ItemData[36];
// Inventory // Inventory
for (int i = 9; i < 36; i++) { for (int i = 9; i < 36; i++) {
contents[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); contents[i] = ItemTranslator.translateToBedrock(inventory.getItem(i));
} }
// Hotbar // Hotbar
for (int i = 36; i < 45; i++) { for (int i = 36; i < 45; i++) {
contents[i - 36] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); contents[i - 36] = ItemTranslator.translateToBedrock(inventory.getItem(i));
} }
inventoryContentPacket.setContents(contents); inventoryContentPacket.setContents(contents);
session.sendUpstreamPacket(inventoryContentPacket); session.sendUpstreamPacket(inventoryContentPacket);
@ -74,7 +73,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
armorContentPacket.setContainerId(ContainerId.ARMOR); armorContentPacket.setContainerId(ContainerId.ARMOR);
contents = new ItemData[4]; contents = new ItemData[4];
for (int i = 5; i < 9; i++) { for (int i = 5; i < 9; i++) {
contents[i - 5] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); contents[i - 5] = ItemTranslator.translateToBedrock(inventory.getItem(i));
} }
armorContentPacket.setContents(contents); armorContentPacket.setContents(contents);
session.sendUpstreamPacket(armorContentPacket); session.sendUpstreamPacket(armorContentPacket);
@ -82,7 +81,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
// Offhand // Offhand
InventoryContentPacket offhandPacket = new InventoryContentPacket(); InventoryContentPacket offhandPacket = new InventoryContentPacket();
offhandPacket.setContainerId(ContainerId.OFFHAND); offhandPacket.setContainerId(ContainerId.OFFHAND);
offhandPacket.setContents(new ItemData[]{Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(45))}); offhandPacket.setContents(new ItemData[]{ItemTranslator.translateToBedrock(inventory.getItem(45))});
session.sendUpstreamPacket(offhandPacket); session.sendUpstreamPacket(offhandPacket);
} }
@ -101,7 +100,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
if (session.getGameMode() == GameMode.CREATIVE) { if (session.getGameMode() == GameMode.CREATIVE) {
slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK); slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK);
}else{ }else{
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(i)));
} }
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
@ -126,12 +125,12 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
slotPacket.setContainerId(ContainerId.CURSOR); slotPacket.setContainerId(ContainerId.CURSOR);
slotPacket.setSlot(slot + 27); slotPacket.setSlot(slot + 27);
} }
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(slot))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(slot)));
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
} else if (slot == 45) { } else if (slot == 45) {
InventoryContentPacket offhandPacket = new InventoryContentPacket(); InventoryContentPacket offhandPacket = new InventoryContentPacket();
offhandPacket.setContainerId(ContainerId.OFFHAND); offhandPacket.setContainerId(ContainerId.OFFHAND);
offhandPacket.setContents(new ItemData[]{Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(slot))}); offhandPacket.setContents(new ItemData[]{ItemTranslator.translateToBedrock(inventory.getItem(slot))});
session.sendUpstreamPacket(offhandPacket); session.sendUpstreamPacket(offhandPacket);
} }
} }
@ -202,7 +201,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
if (action.getToItem().getId() == 0) { if (action.getToItem().getId() == 0) {
javaItem = new ItemStack(-1, 0, null); javaItem = new ItemStack(-1, 0, null);
} else { } else {
javaItem = Translators.getItemTranslator().translateToJava(session, action.getToItem()); javaItem = ItemTranslator.translateToJava(action.getToItem());
} }
ClientCreativeInventoryActionPacket creativePacket = new ClientCreativeInventoryActionPacket(javaSlot, javaItem); ClientCreativeInventoryActionPacket creativePacket = new ClientCreativeInventoryActionPacket(javaSlot, javaItem);
session.sendDownstreamPacket(creativePacket); session.sendDownstreamPacket(creativePacket);
@ -210,13 +209,13 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
break; break;
case ContainerId.CURSOR: case ContainerId.CURSOR:
if (action.getSlot() == 0) { if (action.getSlot() == 0) {
session.getInventory().setCursor(Translators.getItemTranslator().translateToJava(session, action.getToItem())); session.getInventory().setCursor(ItemTranslator.translateToJava(action.getToItem()));
} }
break; break;
case ContainerId.NONE: case ContainerId.NONE:
if (action.getSource().getType() == InventorySource.Type.WORLD_INTERACTION if (action.getSource().getType() == InventorySource.Type.WORLD_INTERACTION
&& action.getSource().getFlag() == InventorySource.Flag.DROP_ITEM) { && action.getSource().getFlag() == InventorySource.Flag.DROP_ITEM) {
javaItem = Translators.getItemTranslator().translateToJava(session, action.getToItem()); javaItem = ItemTranslator.translateToJava(action.getToItem());
ClientCreativeInventoryActionPacket creativeDropPacket = new ClientCreativeInventoryActionPacket(-1, javaItem); ClientCreativeInventoryActionPacket creativeDropPacket = new ClientCreativeInventoryActionPacket(-1, javaItem);
session.sendDownstreamPacket(creativeDropPacket); session.sendDownstreamPacket(creativeDropPacket);
} }

View File

@ -38,9 +38,9 @@ import com.nukkitx.protocol.bedrock.data.InventorySource;
import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.data.ItemData;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.inventory.SlotType; import org.geysermc.connector.network.translators.inventory.SlotType;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
import java.util.*; import java.util.*;
@ -61,13 +61,13 @@ public class InventoryActionDataTranslator {
worldAction = action; worldAction = action;
} else if (action.getSource().getContainerId() == ContainerId.CURSOR && action.getSlot() == 0) { } else if (action.getSource().getContainerId() == ContainerId.CURSOR && action.getSlot() == 0) {
cursorAction = action; cursorAction = action;
ItemData translatedCursor = Translators.getItemTranslator().translateToBedrock(session, session.getInventory().getCursor()); ItemData translatedCursor = ItemTranslator.translateToBedrock(session.getInventory().getCursor());
if (!translatedCursor.equals(action.getFromItem())) { if (!translatedCursor.equals(action.getFromItem())) {
refresh = true; refresh = true;
} }
} else { } else {
containerAction = action; containerAction = action;
ItemData translatedItem = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(translator.bedrockSlotToJava(action))); ItemData translatedItem = ItemTranslator.translateToBedrock(inventory.getItem(translator.bedrockSlotToJava(action)));
if (!translatedItem.equals(action.getFromItem())) { if (!translatedItem.equals(action.getFromItem())) {
refresh = true; refresh = true;
} }

View File

@ -31,8 +31,8 @@ import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
@AllArgsConstructor @AllArgsConstructor
@ -49,7 +49,7 @@ public class ChestInventoryUpdater extends InventoryUpdater {
ItemData[] bedrockItems = new ItemData[paddedSize]; ItemData[] bedrockItems = new ItemData[paddedSize];
for (int i = 0; i < bedrockItems.length; i++) { for (int i = 0; i < bedrockItems.length; i++) {
if (i < translator.size) { if (i < translator.size) {
bedrockItems[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); bedrockItems[i] = ItemTranslator.translateToBedrock(inventory.getItem(i));
} else { } else {
bedrockItems[i] = UNUSUABLE_SPACE_BLOCK; bedrockItems[i] = UNUSUABLE_SPACE_BLOCK;
} }
@ -69,7 +69,7 @@ public class ChestInventoryUpdater extends InventoryUpdater {
InventorySlotPacket slotPacket = new InventorySlotPacket(); InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(inventory.getId()); slotPacket.setContainerId(inventory.getId());
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
return true; return true;
} }

View File

@ -30,8 +30,8 @@ import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
public class ContainerInventoryUpdater extends InventoryUpdater { public class ContainerInventoryUpdater extends InventoryUpdater {
@Override @Override
@ -40,7 +40,7 @@ public class ContainerInventoryUpdater extends InventoryUpdater {
ItemData[] bedrockItems = new ItemData[translator.size]; ItemData[] bedrockItems = new ItemData[translator.size];
for (int i = 0; i < bedrockItems.length; i++) { for (int i = 0; i < bedrockItems.length; i++) {
bedrockItems[translator.javaSlotToBedrock(i)] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)); bedrockItems[translator.javaSlotToBedrock(i)] = ItemTranslator.translateToBedrock(inventory.getItem(i));
} }
InventoryContentPacket contentPacket = new InventoryContentPacket(); InventoryContentPacket contentPacket = new InventoryContentPacket();
@ -57,7 +57,7 @@ public class ContainerInventoryUpdater extends InventoryUpdater {
InventorySlotPacket slotPacket = new InventorySlotPacket(); InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(inventory.getId()); slotPacket.setContainerId(inventory.getId());
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
return true; return true;
} }

View File

@ -29,8 +29,8 @@ import com.nukkitx.protocol.bedrock.data.ContainerId;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
public class CursorInventoryUpdater extends InventoryUpdater { public class CursorInventoryUpdater extends InventoryUpdater {
@Override @Override
@ -44,7 +44,7 @@ public class CursorInventoryUpdater extends InventoryUpdater {
InventorySlotPacket slotPacket = new InventorySlotPacket(); InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(ContainerId.CURSOR); slotPacket.setContainerId(ContainerId.CURSOR);
slotPacket.setSlot(bedrockSlot); slotPacket.setSlot(bedrockSlot);
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(i)));
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
} }
} }
@ -57,7 +57,7 @@ public class CursorInventoryUpdater extends InventoryUpdater {
InventorySlotPacket slotPacket = new InventorySlotPacket(); InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(ContainerId.CURSOR); slotPacket.setContainerId(ContainerId.CURSOR);
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
return true; return true;
} }

View File

@ -31,15 +31,15 @@ import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
public abstract class InventoryUpdater { public abstract class InventoryUpdater {
public void updateInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { public void updateInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
ItemData[] bedrockItems = new ItemData[36]; ItemData[] bedrockItems = new ItemData[36];
for (int i = 0; i < 36; i++) { for (int i = 0; i < 36; i++) {
final int offset = i < 9 ? 27 : -9; final int offset = i < 9 ? 27 : -9;
bedrockItems[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(translator.size + i + offset)); bedrockItems[i] = ItemTranslator.translateToBedrock(inventory.getItem(translator.size + i + offset));
} }
InventoryContentPacket contentPacket = new InventoryContentPacket(); InventoryContentPacket contentPacket = new InventoryContentPacket();
contentPacket.setContainerId(ContainerId.INVENTORY); contentPacket.setContainerId(ContainerId.INVENTORY);
@ -52,7 +52,7 @@ public abstract class InventoryUpdater {
InventorySlotPacket slotPacket = new InventorySlotPacket(); InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(ContainerId.INVENTORY); slotPacket.setContainerId(ContainerId.INVENTORY);
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot))); slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
session.sendUpstreamPacket(slotPacket); session.sendUpstreamPacket(slotPacket);
return true; return true;
} }

View File

@ -1,91 +1,85 @@
/* /*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* *
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.connector.utils; package org.geysermc.connector.network.translators.item;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.nukkitx.nbt.NbtUtils; import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.nbt.stream.NBTInputStream;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.data.ItemData;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
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 org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.network.translators.item.ToolItemEntry;
import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry;
import java.io.*; import java.io.ByteArrayInputStream;
import java.util.*; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class Toolbox { /**
* Registry for anything item related.
*/
public class ItemRegistry {
private static final Map<String, ItemEntry> JAVA_IDENTIFIER_MAP = new HashMap<>();
public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
public static final CompoundTag BIOMES;
public static final ItemData[] CREATIVE_ITEMS; public static final ItemData[] CREATIVE_ITEMS;
public static final List<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>(); public static final List<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>();
public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>();
public static CompoundTag ENTITY_IDENTIFIERS; // Shield ID, used in Entity.java
public static final int SHIELD = 829;
// Boat ID, used in BedrockInventoryTransactionTranslator.java
public static final int BOAT = 333;
public static int BARRIER_INDEX = 0; public static int BARRIER_INDEX = 0;
public static void init() {
// no-op
}
static { static {
/* Load biomes */
InputStream biomestream = GeyserConnector.class.getClassLoader().getResourceAsStream("bedrock/biome_definitions.dat");
if (biomestream == null) {
throw new AssertionError("Unable to find bedrock/biome_definitions.dat");
}
CompoundTag biomesTag;
try (NBTInputStream biomenbtInputStream = NbtUtils.createNetworkReader(biomestream)){
biomesTag = (CompoundTag) biomenbtInputStream.readTag();
BIOMES = biomesTag;
} catch (Exception ex) {
GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?");
throw new AssertionError(ex);
}
/* Load item palette */ /* Load item palette */
InputStream stream = getResource("bedrock/items.json"); InputStream stream = FileUtils.getResource("bedrock/items.json");
TypeReference<List<JsonNode>> itemEntriesType = new TypeReference<List<JsonNode>>() { TypeReference<List<JsonNode>> itemEntriesType = new TypeReference<List<JsonNode>>() {
}; };
List<JsonNode> itemEntries; List<JsonNode> itemEntries;
try { try {
itemEntries = JSON_MAPPER.readValue(stream, itemEntriesType); itemEntries = GeyserConnector.JSON_MAPPER.readValue(stream, itemEntriesType);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load Bedrock runtime item IDs", e); throw new AssertionError("Unable to load Bedrock runtime item IDs", e);
} }
@ -94,11 +88,11 @@ public class Toolbox {
ITEMS.add(new StartGamePacket.ItemEntry(entry.get("name").textValue(), (short) entry.get("id").intValue())); ITEMS.add(new StartGamePacket.ItemEntry(entry.get("name").textValue(), (short) entry.get("id").intValue()));
} }
stream = getResource("mappings/items.json"); stream = FileUtils.getResource("mappings/items.json");
JsonNode items; JsonNode items;
try { try {
items = JSON_MAPPER.readTree(stream); items = GeyserConnector.JSON_MAPPER.readTree(stream);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load Java runtime item IDs", e); throw new AssertionError("Unable to load Java runtime item IDs", e);
} }
@ -139,22 +133,12 @@ public class Toolbox {
itemIndex++; itemIndex++;
} }
// Load particle/effect mappings
EffectUtils.init();
// Load sound mappings
SoundUtils.init();
// Load the locale data
LocaleUtils.init();
// Load sound handlers
SoundHandlerRegistry.init();
/* Load creative items */ /* Load creative items */
stream = getResource("bedrock/creative_items.json"); stream = FileUtils.getResource("bedrock/creative_items.json");
JsonNode creativeItemEntries; JsonNode creativeItemEntries;
try { try {
creativeItemEntries = JSON_MAPPER.readTree(stream).get("items"); creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items");
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load creative items", e); throw new AssertionError("Unable to load creative items", e);
} }
@ -179,33 +163,51 @@ public class Toolbox {
} }
} }
CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]); CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]);
/* Load entity identifiers */
stream = Toolbox.getResource("bedrock/entity_identifiers.dat");
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) {
ENTITY_IDENTIFIERS = (CompoundTag) nbtInputStream.readTag();
} catch (Exception e) {
throw new AssertionError("Unable to get entities from entity identifiers", e);
}
} }
/** /**
* Get an InputStream for the given resource path, throws AssertionError if resource is not found * Gets an {@link ItemEntry} from the given {@link ItemStack}.
* *
* @param resource Resource to get * @param stack the item stack
* @return InputStream of the given resource * @return an item entry from the given item stack
*/ */
public static InputStream getResource(String resource) { public static ItemEntry getItem(ItemStack stack) {
InputStream stream = Toolbox.class.getClassLoader().getResourceAsStream(resource); return ITEM_ENTRIES.get(stack.getId());
if (stream == null) {
throw new AssertionError("Unable to find resource: " + resource);
}
return stream;
} }
public static void init() { /**
// no-op * Gets an {@link ItemEntry} from the given {@link ItemData}.
*
* @param data the item data
* @return an item entry from the given item data
*/
public static ItemEntry getItem(ItemData data) {
for (ItemEntry itemEntry : ITEM_ENTRIES.values()) {
if (itemEntry.getBedrockId() == data.getId() && (itemEntry.getBedrockData() == data.getDamage() || itemEntry.getJavaIdentifier().endsWith("potion"))) {
return itemEntry;
}
}
// If item find was unsuccessful first time, we try again while ignoring damage
// Fixes piston, sticky pistons, dispensers and droppers turning into air from creative inventory
for (ItemEntry itemEntry : ITEM_ENTRIES.values()) {
if (itemEntry.getBedrockId() == data.getId()) {
return itemEntry;
}
}
GeyserConnector.getInstance().getLogger().debug("Missing mapping for bedrock item " + data.getId() + ":" + data.getDamage());
return ItemEntry.AIR;
} }
}
/**
* Gets an {@link ItemEntry} from the given Minecraft: Java Edition
* block state identifier.
*
* @param javaIdentifier the block state identifier
* @return an item entry from the given java edition identifier
*/
public static ItemEntry getItemEntry(String javaIdentifier) {
return JAVA_IDENTIFIER_MAP.computeIfAbsent(javaIdentifier, key -> ITEM_ENTRIES.values()
.stream().filter(itemEntry -> itemEntry.getJavaIdentifier().equals(key)).findFirst().orElse(null));
}
}

View File

@ -1,57 +1,63 @@
/* /*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* *
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.connector.network.translators.item; package org.geysermc.connector.network.translators.item;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.nbt.tag.Tag;
import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.data.ItemData;
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 org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.*;
import org.geysermc.connector.utils.Toolbox;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.util.*; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ItemTranslator { public abstract class ItemTranslator {
private Int2ObjectMap<ItemStackTranslator> itemTranslators = new Int2ObjectOpenHashMap(); private static final Int2ObjectMap<ItemTranslator> ITEM_STACK_TRANSLATORS = new Int2ObjectOpenHashMap<>();
private List<NbtItemStackTranslator> nbtItemTranslators; private static final List<NbtItemStackTranslator> NBT_TRANSLATORS;
private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>();
// Shield ID, used in Entity.java protected ItemTranslator() {
public static final int SHIELD = 829; }
// Boat ID, used in BedrockInventoryTransactionTranslator.java
public static final int BOAT = 333;
public void init() { public static void init() {
// no-op
}
static {
/* Load item translators */
Reflections ref = new Reflections("org.geysermc.connector.network.translators.item"); Reflections ref = new Reflections("org.geysermc.connector.network.translators.item");
Map<NbtItemStackTranslator, Integer> loadedNbtItemTranslators = new HashMap<>(); Map<NbtItemStackTranslator, Integer> loadedNbtItemTranslators = new HashMap<>();
@ -66,34 +72,33 @@ public class ItemTranslator {
loadedNbtItemTranslators.put(nbtItemTranslator, priority); loadedNbtItemTranslators.put(nbtItemTranslator, priority);
continue; continue;
} }
ItemStackTranslator itemStackTranslator = (ItemStackTranslator) clazz.newInstance(); ItemTranslator itemStackTranslator = (ItemTranslator) clazz.newInstance();
List<ItemEntry> appliedItems = itemStackTranslator.getAppliedItems(); List<ItemEntry> appliedItems = itemStackTranslator.getAppliedItems();
for (ItemEntry item : appliedItems) { for (ItemEntry item : appliedItems) {
ItemStackTranslator registered = itemTranslators.get(item.getJavaId()); ItemTranslator registered = ITEM_STACK_TRANSLATORS.get(item.getJavaId());
if (registered != null) { if (registered != null) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + "." + GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + "." +
" Item translator " + registered.getClass().getCanonicalName() + " is already registered for the item " + item.getJavaIdentifier()); " Item translator " + registered.getClass().getCanonicalName() + " is already registered for the item " + item.getJavaIdentifier());
continue; continue;
} }
itemTranslators.put(item.getJavaId(), itemStackTranslator); ITEM_STACK_TRANSLATORS.put(item.getJavaId(), itemStackTranslator);
} }
} catch (InstantiationException | IllegalAccessException e) { } catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + "."); GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + ".");
} }
} }
nbtItemTranslators = loadedNbtItemTranslators.keySet().stream() NBT_TRANSLATORS = loadedNbtItemTranslators.keySet().stream().sorted(Comparator.comparingInt(loadedNbtItemTranslators::get)).collect(Collectors.toList());
.sorted(Comparator.comparingInt(value -> loadedNbtItemTranslators.get(value))).collect(Collectors.toList());
} }
public ItemStack translateToJava(GeyserSession session, ItemData data) { public static ItemStack translateToJava(ItemData data) {
if (data == null) { if (data == null) {
return new ItemStack(0); return new ItemStack(0);
} }
ItemEntry javaItem = getItem(data); ItemEntry javaItem = ItemRegistry.getItem(data);
ItemStack itemStack; ItemStack itemStack;
ItemStackTranslator itemStackTranslator = itemTranslators.get(javaItem.getJavaId()); ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(javaItem.getJavaId());
if (itemStackTranslator != null) { if (itemStackTranslator != null) {
itemStack = itemStackTranslator.translateToJava(data, javaItem); itemStack = itemStackTranslator.translateToJava(data, javaItem);
} else { } else {
@ -101,7 +106,7 @@ public class ItemTranslator {
} }
if (itemStack != null && itemStack.getNbt() != null) { if (itemStack != null && itemStack.getNbt() != null) {
for (NbtItemStackTranslator translator : nbtItemTranslators) { for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
if (translator.acceptItem(javaItem)) { if (translator.acceptItem(javaItem)) {
translator.translateToJava(itemStack.getNbt(), javaItem); translator.translateToJava(itemStack.getNbt(), javaItem);
} }
@ -110,24 +115,24 @@ public class ItemTranslator {
return itemStack; return itemStack;
} }
public ItemData translateToBedrock(GeyserSession session, ItemStack stack) { public static ItemData translateToBedrock(ItemStack stack) {
if (stack == null) { if (stack == null) {
return ItemData.AIR; return ItemData.AIR;
} }
ItemEntry bedrockItem = getItem(stack); ItemEntry bedrockItem = ItemRegistry.getItem(stack);
ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), stack.getNbt() != null ? stack.getNbt().clone() : null); ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), stack.getNbt() != null ? stack.getNbt().clone() : null);
if (itemStack.getNbt() != null) { if (itemStack.getNbt() != null) {
for (NbtItemStackTranslator translator : nbtItemTranslators) { for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
if (translator.acceptItem(bedrockItem)) { if (translator.acceptItem(bedrockItem)) {
translator.translateToBedrock(itemStack.getNbt(), bedrockItem); translator.translateToBedrock(itemStack.getNbt(), bedrockItem);
} }
} }
} }
ItemStackTranslator itemStackTranslator = itemTranslators.get(bedrockItem.getJavaId()); ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
if (itemStackTranslator != null) { if (itemStackTranslator != null) {
return itemStackTranslator.translateToBedrock(itemStack, bedrockItem); return itemStackTranslator.translateToBedrock(itemStack, bedrockItem);
} else { } else {
@ -135,37 +140,216 @@ public class ItemTranslator {
} }
} }
public ItemEntry getItem(ItemStack stack) { private static final ItemTranslator DEFAULT_TRANSLATOR = new ItemTranslator() {
return Toolbox.ITEM_ENTRIES.get(stack.getId());
}
public ItemEntry getItem(ItemData data) {
for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.values()) {
if (itemEntry.getBedrockId() == data.getId() && (itemEntry.getBedrockData() == data.getDamage() || itemEntry.getJavaIdentifier().endsWith("potion"))) {
return itemEntry;
}
}
// If item find was unsuccessful first time, we try again while ignoring damage
// Fixes piston, sticky pistons, dispensers and droppers turning into air from creative inventory
for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.values()) {
if (itemEntry.getBedrockId() == data.getId()) {
return itemEntry;
}
}
GeyserConnector.getInstance().getLogger().debug("Missing mapping for bedrock item " + data.getId() + ":" + data.getDamage());
return ItemEntry.AIR;
}
public ItemEntry getItemEntry(String javaIdentifier) {
return javaIdentifierMap.computeIfAbsent(javaIdentifier, key -> Toolbox.ITEM_ENTRIES.values()
.stream().filter(itemEntry -> itemEntry.getJavaIdentifier().equals(key)).findFirst().orElse(null));
}
private static final ItemStackTranslator DEFAULT_TRANSLATOR = new ItemStackTranslator() {
@Override @Override
public List<ItemEntry> getAppliedItems() { public List<ItemEntry> getAppliedItems() {
return null; return null;
} }
}; };
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack == null) {
return ItemData.AIR;
}
if (itemStack.getNbt() == null) {
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount());
}
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt()));
}
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
if (itemData == null) return null;
if (itemData.getTag() == null) {
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), new com.github.steveice10.opennbt.tag.builtin.CompoundTag(""));
}
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT(itemData.getTag()));
}
public abstract List<ItemEntry> getAppliedItems();
public CompoundTag translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) {
Map<String, Tag<?>> javaValue = new HashMap<>();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = tag.get(str);
com.nukkitx.nbt.tag.Tag<?> translatedTag = translateToBedrockNBT(javaTag);
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
return new CompoundTag(tag.getName(), javaValue);
}
private Tag<?> translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) {
if (tag instanceof ByteArrayTag) {
ByteArrayTag byteArrayTag = (ByteArrayTag) tag;
return new com.nukkitx.nbt.tag.ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof ByteTag) {
ByteTag byteTag = (ByteTag) tag;
return new com.nukkitx.nbt.tag.ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof DoubleTag) {
DoubleTag doubleTag = (DoubleTag) tag;
return new com.nukkitx.nbt.tag.DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof FloatTag) {
FloatTag floatTag = (FloatTag) tag;
return new com.nukkitx.nbt.tag.FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof IntArrayTag) {
IntArrayTag intArrayTag = (IntArrayTag) tag;
return new com.nukkitx.nbt.tag.IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof IntTag) {
IntTag intTag = (IntTag) tag;
return new com.nukkitx.nbt.tag.IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof LongArrayTag) {
LongArrayTag longArrayTag = (LongArrayTag) tag;
return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof LongTag) {
LongTag longTag = (LongTag) tag;
return new com.nukkitx.nbt.tag.LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof ShortTag) {
ShortTag shortTag = (ShortTag) tag;
return new com.nukkitx.nbt.tag.ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof StringTag) {
StringTag stringTag = (StringTag) tag;
return new com.nukkitx.nbt.tag.StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
List<Tag<?>> tagList = new ArrayList<>();
for (com.github.steveice10.opennbt.tag.builtin.Tag value : listTag) {
tagList.add(translateToBedrockNBT(value));
}
Class<?> clazz = CompoundTag.class;
if (!tagList.isEmpty()) {
clazz = tagList.get(0).getClass();
}
return new com.nukkitx.nbt.tag.ListTag(listTag.getName(), clazz, tagList);
}
if (tag instanceof com.github.steveice10.opennbt.tag.builtin.CompoundTag) {
com.github.steveice10.opennbt.tag.builtin.CompoundTag compoundTag = (com.github.steveice10.opennbt.tag.builtin.CompoundTag) tag;
return translateNbtToBedrock(compoundTag);
}
return null;
}
public com.github.steveice10.opennbt.tag.builtin.CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) {
com.github.steveice10.opennbt.tag.builtin.CompoundTag javaTag = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(tag.getName());
Map<String, com.github.steveice10.opennbt.tag.builtin.Tag> javaValue = javaTag.getValue();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
Tag<?> bedrockTag = tag.get(str);
com.github.steveice10.opennbt.tag.builtin.Tag translatedTag = translateToJavaNBT(bedrockTag);
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
javaTag.setValue(javaValue);
return javaTag;
}
private com.github.steveice10.opennbt.tag.builtin.Tag translateToJavaNBT(com.nukkitx.nbt.tag.Tag<?> tag) {
if (tag instanceof com.nukkitx.nbt.tag.ByteArrayTag) {
com.nukkitx.nbt.tag.ByteArrayTag byteArrayTag = (com.nukkitx.nbt.tag.ByteArrayTag) tag;
return new ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ByteTag) {
com.nukkitx.nbt.tag.ByteTag byteTag = (com.nukkitx.nbt.tag.ByteTag) tag;
return new ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.DoubleTag) {
com.nukkitx.nbt.tag.DoubleTag doubleTag = (com.nukkitx.nbt.tag.DoubleTag) tag;
return new DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.FloatTag) {
com.nukkitx.nbt.tag.FloatTag floatTag = (com.nukkitx.nbt.tag.FloatTag) tag;
return new FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntArrayTag) {
com.nukkitx.nbt.tag.IntArrayTag intArrayTag = (com.nukkitx.nbt.tag.IntArrayTag) tag;
return new IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntTag) {
com.nukkitx.nbt.tag.IntTag intTag = (com.nukkitx.nbt.tag.IntTag) tag;
return new IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongArrayTag) {
com.nukkitx.nbt.tag.LongArrayTag longArrayTag = (com.nukkitx.nbt.tag.LongArrayTag) tag;
return new LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongTag) {
com.nukkitx.nbt.tag.LongTag longTag = (com.nukkitx.nbt.tag.LongTag) tag;
return new LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ShortTag) {
com.nukkitx.nbt.tag.ShortTag shortTag = (com.nukkitx.nbt.tag.ShortTag) tag;
return new ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.StringTag) {
com.nukkitx.nbt.tag.StringTag stringTag = (com.nukkitx.nbt.tag.StringTag) tag;
return new StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ListTag) {
com.nukkitx.nbt.tag.ListTag<?> listTag = (com.nukkitx.nbt.tag.ListTag<?>) tag;
List<com.github.steveice10.opennbt.tag.builtin.Tag> tags = new ArrayList<>();
for (Object value : listTag.getValue()) {
if (!(value instanceof com.nukkitx.nbt.tag.Tag))
continue;
com.nukkitx.nbt.tag.Tag<?> tagValue = (com.nukkitx.nbt.tag.Tag<?>) value;
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = translateToJavaNBT(tagValue);
if (javaTag != null)
tags.add(javaTag);
}
return new ListTag(listTag.getName(), tags);
}
if (tag instanceof com.nukkitx.nbt.tag.CompoundTag) {
com.nukkitx.nbt.tag.CompoundTag compoundTag = (com.nukkitx.nbt.tag.CompoundTag) tag;
return translateToJavaNBT(compoundTag);
}
return null;
}
} }

View File

@ -0,0 +1,45 @@
/*
* 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/Geyser
*
*/
package org.geysermc.connector.network.translators.item;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
public class NbtItemStackTranslator {
public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) {
}
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
}
public boolean acceptItem(ItemEntry itemEntry) {
return true;
}
}

View File

@ -27,25 +27,30 @@ package org.geysermc.connector.network.translators.item.translators;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.CompoundTagBuilder;
import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.data.ItemData;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.ItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.ItemUtils;
import org.geysermc.connector.utils.Toolbox;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ItemRemapper @ItemRemapper
public class BannerTranslator extends ItemStackTranslator { public class BannerTranslator extends ItemTranslator {
private List<ItemEntry> appliedItems; private List<ItemEntry> appliedItems;
public BannerTranslator() { public BannerTranslator() {
appliedItems = Toolbox.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("banner")).collect(Collectors.toList()); appliedItems = ItemRegistry.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("banner")).collect(Collectors.toList());
} }
@Override @Override
@ -59,7 +64,7 @@ public class BannerTranslator extends ItemStackTranslator {
ListTag patterns = blockEntityTag.get("Patterns"); ListTag patterns = blockEntityTag.get("Patterns");
CompoundTagBuilder builder = itemData.getTag().toBuilder(); CompoundTagBuilder builder = itemData.getTag().toBuilder();
builder.tag(ItemUtils.convertBannerPattern(patterns)); builder.tag(convertBannerPattern(patterns));
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.buildRootTag()); itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.buildRootTag());
} }
@ -75,10 +80,10 @@ public class BannerTranslator extends ItemStackTranslator {
com.nukkitx.nbt.tag.CompoundTag nbtTag = itemData.getTag(); com.nukkitx.nbt.tag.CompoundTag nbtTag = itemData.getTag();
if (nbtTag.contains("Patterns")) { if (nbtTag.contains("Patterns")) {
com.nukkitx.nbt.tag.ListTag patterns = (com.nukkitx.nbt.tag.ListTag) nbtTag.get("Patterns"); com.nukkitx.nbt.tag.ListTag<?> patterns = nbtTag.get("Patterns");
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag");
blockEntityTag.put(ItemUtils.convertBannerPattern(patterns)); blockEntityTag.put(convertBannerPattern(patterns));
itemStack.getNbt().put(blockEntityTag); itemStack.getNbt().put(blockEntityTag);
} }
@ -90,4 +95,73 @@ public class BannerTranslator extends ItemStackTranslator {
public List<ItemEntry> getAppliedItems() { public List<ItemEntry> getAppliedItems() {
return appliedItems; return appliedItems;
} }
/**
* Convert a list of patterns from Java nbt to Bedrock nbt
*
* @param patterns The patterns to convert
* @return The new converted patterns
*/
public static com.nukkitx.nbt.tag.ListTag convertBannerPattern(ListTag patterns) {
List<com.nukkitx.nbt.tag.CompoundTag> tagsList = new ArrayList<>();
for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) {
com.nukkitx.nbt.tag.CompoundTag newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag);
if (newPatternTag != null) {
tagsList.add(newPatternTag);
}
}
return new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList);
}
/**
* Convert the Java edition banner pattern nbt to Bedrock edition, null if the pattern doesn't exist
*
* @param pattern Java edition pattern nbt
* @return The Bedrock edition format pattern nbt
*/
public static com.nukkitx.nbt.tag.CompoundTag getBedrockBannerPattern(CompoundTag pattern) {
String patternName = (String) pattern.get("Pattern").getValue();
// Return null if its the globe pattern as it doesn't exist on bedrock
if (patternName.equals("glb")) {
return null;
}
return CompoundTagBuilder.builder()
.intTag("Color", 15 - (int) pattern.get("Color").getValue())
.stringTag("Pattern", (String) pattern.get("Pattern").getValue())
.stringTag("Pattern", patternName)
.buildRootTag();
}
/**
* Convert a list of patterns from Bedrock nbt to Java nbt
*
* @param patterns The patterns to convert
* @return The new converted patterns
*/
public static ListTag convertBannerPattern(com.nukkitx.nbt.tag.ListTag<?> patterns) {
List<Tag> tagsList = new ArrayList<>();
for (Object patternTag : patterns.getValue()) {
CompoundTag newPatternTag = getJavaBannerPattern((com.nukkitx.nbt.tag.CompoundTag) patternTag);
tagsList.add(newPatternTag);
}
return new ListTag("Patterns", tagsList);
}
/**
* Convert the Bedrock edition banner pattern nbt to Java edition
*
* @param pattern Bedorck edition pattern nbt
* @return The Java edition format pattern nbt
*/
public static CompoundTag getJavaBannerPattern(com.nukkitx.nbt.tag.CompoundTag pattern) {
Map<String, Tag> tags = new HashMap<>();
tags.put("Color", new IntTag("Color", 15 - pattern.getInt("Color")));
tags.put("Pattern", new StringTag("Pattern", pattern.getString("Pattern")));
return new CompoundTag("", tags);
}
} }

View File

@ -30,22 +30,22 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag; import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.data.ItemData;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.ItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.Potion; import org.geysermc.connector.network.translators.item.Potion;
import org.geysermc.connector.utils.Toolbox;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ItemRemapper @ItemRemapper
public class PotionTranslator extends ItemStackTranslator { public class PotionTranslator extends ItemTranslator {
private List<ItemEntry> appliedItems; private List<ItemEntry> appliedItems;
public PotionTranslator() { public PotionTranslator() {
appliedItems = Toolbox.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("potion")).collect(Collectors.toList()); appliedItems = ItemRegistry.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("potion")).collect(Collectors.toList());
} }
@Override @Override

View File

@ -34,7 +34,7 @@ import net.kyori.text.TextComponent;
import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.text.serializer.gson.GsonComponentSerializer;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;

View File

@ -30,7 +30,7 @@ import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag; import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;

View File

@ -30,7 +30,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
@ItemRemapper @ItemRemapper

View File

@ -29,7 +29,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag; import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
@ItemRemapper(priority = 1) @ItemRemapper(priority = 1)

View File

@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt;
import com.github.steveice10.opennbt.tag.builtin.*; import com.github.steveice10.opennbt.tag.builtin.*;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.Enchantment; import org.geysermc.connector.network.translators.item.Enchantment;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;

View File

@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt;
import com.github.steveice10.opennbt.tag.builtin.*; import com.github.steveice10.opennbt.tag.builtin.*;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.FireworkColor; import org.geysermc.connector.utils.FireworkColor;

View File

@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.IntTag;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
@ItemRemapper @ItemRemapper

View File

@ -30,7 +30,7 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.ItemRemapper;
import org.geysermc.connector.network.translators.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
@ItemRemapper @ItemRemapper

View File

@ -42,9 +42,9 @@ import lombok.EqualsAndHashCode;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -64,7 +64,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
switch (recipe.getType()) { switch (recipe.getType()) {
case CRAFTING_SHAPELESS: { case CRAFTING_SHAPELESS: {
ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData(); ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData();
ItemData output = Translators.getItemTranslator().translateToBedrock(session, shapelessRecipeData.getResult()); ItemData output = ItemTranslator.translateToBedrock(shapelessRecipeData.getResult());
output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); //strip NBT output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); //strip NBT
ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients()); ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
for (ItemData[] inputs : inputCombinations) { for (ItemData[] inputs : inputCombinations) {
@ -76,7 +76,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
} }
case CRAFTING_SHAPED: { case CRAFTING_SHAPED: {
ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData(); ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData();
ItemData output = Translators.getItemTranslator().translateToBedrock(session, shapedRecipeData.getResult()); ItemData output = ItemTranslator.translateToBedrock(shapedRecipeData.getResult());
output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); //strip NBT output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); //strip NBT
ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients()); ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
for (ItemData[] inputs : inputCombinations) { for (ItemData[] inputs : inputCombinations) {
@ -103,7 +103,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
} }
Ingredient ingredient = ingredients[i]; Ingredient ingredient = ingredients[i];
Map<GroupedItem, List<ItemData>> groupedByIds = Arrays.stream(ingredient.getOptions()) Map<GroupedItem, List<ItemData>> groupedByIds = Arrays.stream(ingredient.getOptions())
.map(item -> Translators.getItemTranslator().translateToBedrock(session, item)) .map(ItemTranslator::translateToBedrock)
.collect(Collectors.groupingBy(item -> new GroupedItem(item.getId(), item.getCount(), item.getTag()))); .collect(Collectors.groupingBy(item -> new GroupedItem(item.getId(), item.getCount(), item.getTag())));
Set<ItemData> optionSet = new HashSet<>(groupedByIds.size()); Set<ItemData> optionSet = new HashSet<>(groupedByIds.size());
for (Map.Entry<GroupedItem, List<ItemData>> entry : groupedByIds.entrySet()) { for (Map.Entry<GroupedItem, List<ItemData>> entry : groupedByIds.entrySet()) {
@ -111,7 +111,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
GroupedItem groupedItem = entry.getKey(); GroupedItem groupedItem = entry.getKey();
int idCount = 0; int idCount = 0;
//not optimal //not optimal
for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.values()) { for (ItemEntry itemEntry : ItemRegistry.ITEM_ENTRIES.values()) {
if (itemEntry.getBedrockId() == groupedItem.id) { if (itemEntry.getBedrockId() == groupedItem.id) {
idCount++; idCount++;
} }
@ -136,7 +136,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
ItemData[] translatedItems = new ItemData[ingredients.length]; ItemData[] translatedItems = new ItemData[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] = Translators.getItemTranslator().translateToBedrock(session, ingredients[i].getOptions()[0]); translatedItems[i] = ItemTranslator.translateToBedrock(ingredients[i].getOptions()[0]);
} else { } else {
translatedItems[i] = ItemData.AIR; translatedItems[i] = ItemData.AIR;
} }

View File

@ -30,10 +30,10 @@ import org.geysermc.connector.entity.LivingEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityEquipmentPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityEquipmentPacket;
import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.data.ItemData;
import org.geysermc.connector.network.translators.item.ItemTranslator;
@Translator(packet = ServerEntityEquipmentPacket.class) @Translator(packet = ServerEntityEquipmentPacket.class)
public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntityEquipmentPacket> { public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntityEquipmentPacket> {
@ -55,7 +55,7 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntity
} }
LivingEntity livingEntity = (LivingEntity) entity; LivingEntity livingEntity = (LivingEntity) entity;
ItemData item = Translators.getItemTranslator().translateToBedrock(session, packet.getItem()); ItemData item = ItemTranslator.translateToBedrock(packet.getItem());
switch (packet.getSlot()) { switch (packet.getSlot()) {
case HELMET: case HELMET:
livingEntity.setHelmet(item); livingEntity.setHelmet(item);

View File

@ -35,7 +35,7 @@ import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.inventory.PlayerInventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.BlockUtils; import org.geysermc.connector.utils.BlockUtils;
@ -76,7 +76,7 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayer
ItemEntry itemEntry = null; ItemEntry itemEntry = null;
CompoundTag nbtData = new CompoundTag(""); CompoundTag nbtData = new CompoundTag("");
if (item != null) { if (item != null) {
itemEntry = Translators.getItemTranslator().getItem(item); itemEntry = ItemRegistry.getItem(item);
nbtData = item.getNbt(); nbtData = item.getNbt();
} }
double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session) * 20); double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session) * 20);

View File

@ -32,7 +32,7 @@ import com.nukkitx.protocol.bedrock.packet.StopSoundPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.utils.SoundUtils; import org.geysermc.connector.network.translators.sound.SoundRegistry;
@Translator(packet = ServerStopSoundPacket.class) @Translator(packet = ServerStopSoundPacket.class)
public class JavaPlayerStopSoundTranslator extends PacketTranslator<ServerStopSoundPacket> { public class JavaPlayerStopSoundTranslator extends PacketTranslator<ServerStopSoundPacket> {
@ -48,7 +48,7 @@ public class JavaPlayerStopSoundTranslator extends PacketTranslator<ServerStopSo
session.getConnector().getLogger().debug("Unknown sound packet, we were unable to map this. " + packet.toString()); session.getConnector().getLogger().debug("Unknown sound packet, we were unable to map this. " + packet.toString());
return; return;
} }
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound); SoundRegistry.SoundMapping soundMapping = SoundRegistry.fromJava(packetSound);
session.getConnector().getLogger() session.getConnector().getLogger()
.debug("[StopSound] Sound mapping " + packetSound + " -> " .debug("[StopSound] Sound mapping " + packetSound + " -> "
+ soundMapping + (soundMapping == null ? "[not found]" : "") + soundMapping + (soundMapping == null ? "[not found]" : "")

View File

@ -35,7 +35,6 @@ import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
@ -49,14 +48,14 @@ public class JavaOpenWindowTranslator extends PacketTranslator<ServerOpenWindowP
if (packet.getWindowId() == 0) { if (packet.getWindowId() == 0) {
return; return;
} }
InventoryTranslator newTranslator = Translators.getInventoryTranslators().get(packet.getType()); InventoryTranslator newTranslator = InventoryTranslator.INVENTORY_TRANSLATORS.get(packet.getType());
Inventory openInventory = session.getInventoryCache().getOpenInventory(); Inventory openInventory = session.getInventoryCache().getOpenInventory();
if (newTranslator == null) { if (newTranslator == null) {
if (openInventory != null) { if (openInventory != null) {
ContainerClosePacket closePacket = new ContainerClosePacket(); ContainerClosePacket closePacket = new ContainerClosePacket();
closePacket.setWindowId((byte)openInventory.getId()); closePacket.setWindowId((byte)openInventory.getId());
session.sendUpstreamPacket(closePacket); session.sendUpstreamPacket(closePacket);
Translators.getInventoryTranslators().get(openInventory.getWindowType()).closeInventory(session, openInventory); InventoryTranslator.INVENTORY_TRANSLATORS.get(openInventory.getWindowType()).closeInventory(session, openInventory);
} }
ClientCloseWindowPacket closeWindowPacket = new ClientCloseWindowPacket(packet.getWindowId()); ClientCloseWindowPacket closeWindowPacket = new ClientCloseWindowPacket(packet.getWindowId());
session.sendDownstreamPacket(closeWindowPacket); session.sendDownstreamPacket(closeWindowPacket);
@ -79,7 +78,7 @@ public class JavaOpenWindowTranslator extends PacketTranslator<ServerOpenWindowP
Inventory newInventory = new Inventory(name, packet.getWindowId(), packet.getType(), newTranslator.size + 36); Inventory newInventory = new Inventory(name, packet.getWindowId(), packet.getType(), newTranslator.size + 36);
session.getInventoryCache().cacheInventory(newInventory); session.getInventoryCache().cacheInventory(newInventory);
if (openInventory != null) { if (openInventory != null) {
InventoryTranslator openTranslator = Translators.getInventoryTranslators().get(openInventory.getWindowType()); InventoryTranslator openTranslator = InventoryTranslator.INVENTORY_TRANSLATORS.get(openInventory.getWindowType());
if (!openTranslator.getClass().equals(newTranslator.getClass())) { if (!openTranslator.getClass().equals(newTranslator.getClass())) {
InventoryUtils.closeInventory(session, openInventory.getId()); InventoryUtils.closeInventory(session, openInventory.getId());
GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> InventoryUtils.openInventory(session, newInventory), 500, TimeUnit.MILLISECONDS); GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> InventoryUtils.openInventory(session, newInventory), 500, TimeUnit.MILLISECONDS);

View File

@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerSetSl
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
@ -56,7 +55,7 @@ public class JavaSetSlotTranslator extends PacketTranslator<ServerSetSlotPacket>
if (inventory == null || (packet.getWindowId() != 0 && inventory.getWindowType() == null)) if (inventory == null || (packet.getWindowId() != 0 && inventory.getWindowType() == null))
return; return;
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType()); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
if (translator != null) { if (translator != null) {
inventory.setItem(packet.getSlot(), packet.getItem()); inventory.setItem(packet.getSlot(), packet.getItem());
translator.updateSlot(session, inventory, packet.getSlot()); translator.updateSlot(session, inventory, packet.getSlot());

View File

@ -30,7 +30,6 @@ import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import java.util.Arrays; import java.util.Arrays;
@ -50,7 +49,7 @@ public class JavaWindowItemsTranslator extends PacketTranslator<ServerWindowItem
inventory.setItems(packet.getItems()); inventory.setItems(packet.getItems());
} }
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType()); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
if (translator != null) { if (translator != null) {
translator.updateInventory(session, inventory); translator.updateInventory(session, inventory);
} }

View File

@ -30,7 +30,6 @@ import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
@Translator(packet = ServerWindowPropertyPacket.class) @Translator(packet = ServerWindowPropertyPacket.class)
@ -42,7 +41,7 @@ public class JavaWindowPropertyTranslator extends PacketTranslator<ServerWindowP
if (inventory == null || (packet.getWindowId() != 0 && inventory.getWindowType() == null)) if (inventory == null || (packet.getWindowId() != 0 && inventory.getWindowType() == null))
return; return;
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType()); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
if (translator != null) { if (translator != null) {
translator.updateProperty(session, inventory, packet.getRawProperty(), packet.getValue()); translator.updateProperty(session, inventory, packet.getRawProperty(), packet.getValue());
} }

View File

@ -35,7 +35,7 @@ import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.SoundUtils; import org.geysermc.connector.network.translators.sound.SoundRegistry;
@Translator(packet = ServerPlayBuiltinSoundPacket.class) @Translator(packet = ServerPlayBuiltinSoundPacket.class)
public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayBuiltinSoundPacket> { public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayBuiltinSoundPacket> {
@ -44,7 +44,7 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
public void translate(ServerPlayBuiltinSoundPacket packet, GeyserSession session) { public void translate(ServerPlayBuiltinSoundPacket packet, GeyserSession session) {
String packetSound = packet.getSound().getName(); String packetSound = packet.getSound().getName();
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound); SoundRegistry.SoundMapping soundMapping = SoundRegistry.fromJava(packetSound);
if (soundMapping == null) { if (soundMapping == null) {
session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " not found - " + packet.toString()); session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " not found - " + packet.toString());
return; return;
@ -59,12 +59,12 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
return; return;
} }
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); SoundEvent sound = SoundRegistry.toSoundEvent(soundMapping.getBedrock());
if (sound == null) { if (sound == null) {
sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); sound = SoundRegistry.toSoundEvent(soundMapping.getBedrock());
} }
if (sound == null) { if (sound == null) {
sound = SoundUtils.toSoundEvent(packetSound); sound = SoundRegistry.toSoundEvent(packetSound);
} }
if (sound == null) { if (sound == null) {
session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket

View File

@ -40,7 +40,7 @@ import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.effect.Effect; import org.geysermc.connector.network.translators.effect.Effect;
import org.geysermc.connector.utils.EffectUtils; import org.geysermc.connector.network.translators.effect.EffectRegistry;
import org.geysermc.connector.utils.LocaleUtils; import org.geysermc.connector.utils.LocaleUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -55,7 +55,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
// Some things here are particles, others are not // Some things here are particles, others are not
if (packet.getEffect() instanceof ParticleEffect) { if (packet.getEffect() instanceof ParticleEffect) {
ParticleEffect particleEffect = (ParticleEffect) packet.getEffect(); ParticleEffect particleEffect = (ParticleEffect) packet.getEffect();
Effect geyserEffect = EffectUtils.EFFECTS.get(particleEffect.name()); Effect geyserEffect = EffectRegistry.EFFECTS.get(particleEffect.name());
if (geyserEffect != null) { if (geyserEffect != null) {
String name = geyserEffect.getBedrockName(); String name = geyserEffect.getBedrockName();
effect.setType(LevelEventType.valueOf(name)); effect.setType(LevelEventType.valueOf(name));
@ -119,7 +119,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
session.sendUpstreamPacket(effect); session.sendUpstreamPacket(effect);
} else if (packet.getEffect() instanceof SoundEffect) { } else if (packet.getEffect() instanceof SoundEffect) {
SoundEffect soundEffect = (SoundEffect) packet.getEffect(); SoundEffect soundEffect = (SoundEffect) packet.getEffect();
Effect geyserEffect = EffectUtils.EFFECTS.get(soundEffect.name()); Effect geyserEffect = EffectRegistry.EFFECTS.get(soundEffect.name());
if (geyserEffect != null) { if (geyserEffect != null) {
// Some events are LevelEventTypes, some are SoundEvents. // Some events are LevelEventTypes, some are SoundEvents.
if (geyserEffect.getType().equals("soundLevel")) { if (geyserEffect.getType().equals("soundLevel")) {
@ -129,8 +129,8 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
// Separate case since each RecordEffectData in Java is an individual track in Bedrock // Separate case since each RecordEffectData in Java is an individual track in Bedrock
if (geyserEffect.getJavaName().equals("RECORD")) { if (geyserEffect.getJavaName().equals("RECORD")) {
RecordEffectData recordEffectData = (RecordEffectData) packet.getData(); RecordEffectData recordEffectData = (RecordEffectData) packet.getData();
soundEvent.setSound(EffectUtils.RECORDS.get(recordEffectData.getRecordId())); soundEvent.setSound(EffectRegistry.RECORDS.get(recordEffectData.getRecordId()));
if (EffectUtils.RECORDS.get(recordEffectData.getRecordId()) != SoundEvent.STOP_RECORD) { if (EffectRegistry.RECORDS.get(recordEffectData.getRecordId()) != SoundEvent.STOP_RECORD) {
// Send text packet as it seems to be handled in Java Edition client-side. // Send text packet as it seems to be handled in Java Edition client-side.
TextPacket textPacket = new TextPacket(); TextPacket textPacket = new TextPacket();
textPacket.setType(TextPacket.Type.JUKEBOX_POPUP); textPacket.setType(TextPacket.Type.JUKEBOX_POPUP);
@ -140,7 +140,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
textPacket.setSourceName(null); textPacket.setSourceName(null);
textPacket.setMessage("record.nowPlaying"); textPacket.setMessage("record.nowPlaying");
List<String> params = new ArrayList<>(); List<String> params = new ArrayList<>();
String recordString = "%item." + EffectUtils.RECORDS.get(recordEffectData.getRecordId()).name().toLowerCase() + ".desc"; String recordString = "%item." + EffectRegistry.RECORDS.get(recordEffectData.getRecordId()).name().toLowerCase() + ".desc";
params.add(LocaleUtils.getLocaleString(recordString, session.getClientData().getLanguageCode())); params.add(LocaleUtils.getLocaleString(recordString, session.getClientData().getLanguageCode()));
textPacket.setParameters(params); textPacket.setParameters(params);
session.sendUpstreamPacket(textPacket); session.sendUpstreamPacket(textPacket);

View File

@ -34,7 +34,7 @@ import com.nukkitx.protocol.bedrock.packet.*;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.utils.SoundUtils; import org.geysermc.connector.network.translators.sound.SoundRegistry;
@Translator(packet = ServerPlaySoundPacket.class) @Translator(packet = ServerPlaySoundPacket.class)
public class JavaPlayerPlaySoundTranslator extends PacketTranslator<ServerPlaySoundPacket> { public class JavaPlayerPlaySoundTranslator extends PacketTranslator<ServerPlaySoundPacket> {
@ -51,7 +51,7 @@ public class JavaPlayerPlaySoundTranslator extends PacketTranslator<ServerPlaySo
return; return;
} }
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound.replace("minecraft:", "")); SoundRegistry.SoundMapping soundMapping = SoundRegistry.fromJava(packetSound.replace("minecraft:", ""));
String playsound; String playsound;
if(soundMapping == null || soundMapping.getPlaysound() == null) { if(soundMapping == null || soundMapping.getPlaysound() == null) {
// no mapping // no mapping

View File

@ -34,12 +34,12 @@ import com.nukkitx.protocol.bedrock.packet.SpawnParticleEffectPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.EffectUtils;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import org.geysermc.connector.network.translators.effect.EffectRegistry;
@Translator(packet = ServerSpawnParticlePacket.class) @Translator(packet = ServerSpawnParticlePacket.class)
public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnParticlePacket> { public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnParticlePacket> {
@ -64,7 +64,7 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
break; break;
case ITEM: case ITEM:
ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack(); ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack();
ItemData bedrockItem = Translators.getItemTranslator().translateToBedrock(session, javaItem); ItemData bedrockItem = ItemTranslator.translateToBedrock(javaItem);
int id = bedrockItem.getId(); int id = bedrockItem.getId();
short damage = bedrockItem.getDamage(); short damage = bedrockItem.getDamage();
particle.setType(LevelEventType.PARTICLE_ITEM_BREAK); particle.setType(LevelEventType.PARTICLE_ITEM_BREAK);
@ -83,13 +83,13 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
session.sendUpstreamPacket(particle); session.sendUpstreamPacket(particle);
break; break;
default: default:
LevelEventType typeParticle = EffectUtils.getParticleLevelEventType(packet.getParticle().getType()); LevelEventType typeParticle = EffectRegistry.getParticleLevelEventType(packet.getParticle().getType());
if (typeParticle != null) { if (typeParticle != null) {
particle.setType(typeParticle); particle.setType(typeParticle);
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));
session.sendUpstreamPacket(particle); session.sendUpstreamPacket(particle);
} else { } else {
String stringParticle = EffectUtils.getParticleString(packet.getParticle().getType()); String stringParticle = EffectRegistry.getParticleString(packet.getParticle().getType());
if (stringParticle != null) { if (stringParticle != null) {
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket(); SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
stringPacket.setIdentifier(stringParticle); stringPacket.setIdentifier(stringParticle);

View File

@ -29,7 +29,7 @@ package org.geysermc.connector.network.translators.sound;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemRegistry;
import java.util.Map; import java.util.Map;
@ -66,7 +66,7 @@ public interface BlockSoundInteractionHandler extends SoundInteractionHandler<St
if (itemInHand == null || itemInHand.getId() == 0) { if (itemInHand == null || itemInHand.getId() == 0) {
continue; continue;
} }
String handIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier(); String handIdentifier = ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
boolean contains = false; boolean contains = false;
for (String itemIdentifier : interactionEntry.getKey().items()) { for (String itemIdentifier : interactionEntry.getKey().items()) {
if (handIdentifier.contains(itemIdentifier)) { if (handIdentifier.contains(itemIdentifier)) {

View File

@ -30,7 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemRegistry;
import java.util.Map; import java.util.Map;
@ -67,7 +67,7 @@ public interface EntitySoundInteractionHandler extends SoundInteractionHandler<E
if (itemInHand == null || itemInHand.getId() == 0) { if (itemInHand == null || itemInHand.getId() == 0) {
continue; continue;
} }
String handIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier(); String handIdentifier = ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
boolean contains = false; boolean contains = false;
for (String itemIdentifier : interactionEntry.getKey().items()) { for (String itemIdentifier : interactionEntry.getKey().items()) {
if (handIdentifier.contains(itemIdentifier)) { if (handIdentifier.contains(itemIdentifier)) {

View File

@ -1,56 +1,60 @@
/* /*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
* *
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.connector.utils; package org.geysermc.connector.network.translators.sound;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.data.SoundEvent;
import lombok.Data; import lombok.Data;
import lombok.ToString; import lombok.ToString;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.FileUtils;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
public class SoundUtils { public class SoundRegistry {
private static final Map<String, SoundMapping> SOUNDS; private static final Map<String, SoundMapping> SOUNDS;
private SoundRegistry() {
}
public static void init() { public static void init() {
// no-op // no-op
} }
static { static {
/* Load sound mappings */ /* Load sound mappings */
InputStream stream = Toolbox.getResource("mappings/sounds.json"); InputStream stream = FileUtils.getResource("mappings/sounds.json");
JsonNode soundsTree; JsonNode soundsTree;
try { try {
soundsTree = Toolbox.JSON_MAPPER.readTree(stream); soundsTree = GeyserConnector.JSON_MAPPER.readTree(stream);
} catch (IOException e) { } catch (IOException e) {
throw new AssertionError("Unable to load sound mappings", e); throw new AssertionError("Unable to load sound mappings", e);
} }
@ -83,6 +87,13 @@ public class SoundUtils {
return SOUNDS.get(java); return SOUNDS.get(java);
} }
/**
* Maps a sound name to a sound event, null if one
* does not exist.
*
* @param sound the sound name
* @return a sound event from the given sound
*/
public static SoundEvent toSoundEvent(String sound) { public static SoundEvent toSoundEvent(String sound) {
try { try {
return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_")); return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_"));

View File

@ -30,7 +30,7 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler;
import org.geysermc.connector.network.translators.sound.SoundHandler; import org.geysermc.connector.network.translators.sound.SoundHandler;
@ -39,7 +39,7 @@ public class BucketSoundInteractionHandler implements BlockSoundInteractionHandl
@Override @Override
public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { public void handleInteraction(GeyserSession session, Vector3f position, String identifier) {
String handItemIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier(); String handItemIdentifier = ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
soundEventPacket.setPosition(position); soundEventPacket.setPosition(position);
soundEventPacket.setIdentifier(":"); soundEventPacket.setIdentifier(":");

View File

@ -31,7 +31,7 @@ import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler; import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler;
import org.geysermc.connector.network.translators.sound.SoundHandler; import org.geysermc.connector.network.translators.sound.SoundHandler;
@ -40,7 +40,7 @@ public class MilkCowSoundInteractionHandler implements EntitySoundInteractionHan
@Override @Override
public void handleInteraction(GeyserSession session, Vector3f position, Entity value) { public void handleInteraction(GeyserSession session, Vector3f position, Entity value) {
if (!Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier().equals("minecraft:bucket")) { if (!ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier().equals("minecraft:bucket")) {
return; return;
} }
LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket();

View File

@ -39,7 +39,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.world.block.entity.BlockEntity; import org.geysermc.connector.network.translators.world.block.entity.BlockEntity;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.FileUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.io.InputStream; import java.io.InputStream;
@ -73,7 +73,7 @@ public class BlockTranslator {
static { static {
/* Load block palette */ /* Load block palette */
InputStream stream = Toolbox.getResource("bedrock/runtime_block_states.dat"); InputStream stream = FileUtils.getResource("bedrock/runtime_block_states.dat");
ListTag<CompoundTag> blocksTag; ListTag<CompoundTag> blocksTag;
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) { try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) {
@ -90,10 +90,10 @@ public class BlockTranslator {
} }
} }
stream = Toolbox.getResource("mappings/blocks.json"); stream = FileUtils.getResource("mappings/blocks.json");
JsonNode blocks; JsonNode blocks;
try { try {
blocks = Toolbox.JSON_MAPPER.readTree(stream); blocks = GeyserConnector.JSON_MAPPER.readTree(stream);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load Java block mappings", e); throw new AssertionError("Unable to load Java block mappings", e);
} }

View File

@ -32,8 +32,8 @@ import com.nukkitx.nbt.CompoundTagBuilder;
import com.nukkitx.nbt.tag.IntTag; import com.nukkitx.nbt.tag.IntTag;
import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.nbt.tag.StringTag;
import com.nukkitx.nbt.tag.Tag; import com.nukkitx.nbt.tag.Tag;
import org.geysermc.connector.network.translators.item.translators.BannerTranslator;
import org.geysermc.connector.network.translators.world.block.BlockStateValues; import org.geysermc.connector.network.translators.world.block.BlockStateValues;
import org.geysermc.connector.utils.ItemUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -57,7 +57,7 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement
if (tag.contains("Patterns")) { if (tag.contains("Patterns")) {
ListTag patterns = tag.get("Patterns"); ListTag patterns = tag.get("Patterns");
tags.add(ItemUtils.convertBannerPattern(patterns)); tags.add(BannerTranslator.convertBannerPattern(patterns));
} }
if (tag.contains("CustomName")) { if (tag.contains("CustomName")) {

View File

@ -32,12 +32,49 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.CompoundTagBuilder;
import com.nukkitx.nbt.tag.Tag; import com.nukkitx.nbt.tag.Tag;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.BlockEntityUtils; import org.geysermc.connector.utils.BlockEntityUtils;
import org.reflections.Reflections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public abstract class BlockEntityTranslator { public abstract class BlockEntityTranslator {
public static final Map<String, BlockEntityTranslator> BLOCK_ENTITY_TRANSLATORS = new HashMap<>();
public static ObjectArrayList<RequiresBlockState> REQUIRES_BLOCK_STATE_LIST = new ObjectArrayList<>();
protected BlockEntityTranslator() {
}
public static void init() {
// no-op
}
static {
Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity");
for (Class<?> clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) {
GeyserConnector.getInstance().getLogger().debug("Found annotated block entity: " + clazz.getCanonicalName());
try {
BLOCK_ENTITY_TRANSLATORS.put(clazz.getAnnotation(BlockEntity.class).name(), (BlockEntityTranslator) clazz.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated block entity " + clazz.getCanonicalName() + ".");
}
}
for (Class<?> clazz : ref.getSubTypesOf(RequiresBlockState.class)) {
GeyserConnector.getInstance().getLogger().debug("Found block entity that requires block state: " + clazz.getCanonicalName());
try {
REQUIRES_BLOCK_STATE_LIST.add((RequiresBlockState) clazz.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate required block state " + clazz.getCanonicalName() + ".");
}
}
}
public abstract List<Tag<?>> translateTag(CompoundTag tag, BlockState blockState); public abstract List<Tag<?>> translateTag(CompoundTag tag, BlockState blockState);
public abstract CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z); public abstract CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z);

View File

@ -30,9 +30,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.CompoundTagBuilder;
import com.nukkitx.nbt.tag.Tag; import com.nukkitx.nbt.tag.Tag;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemRegistry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -71,7 +70,7 @@ public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
} }
protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) {
ItemEntry entry = Translators.getItemTranslator().getItemEntry((String) tag.get("id").getValue()); ItemEntry entry = ItemRegistry.getItemEntry((String) tag.get("id").getValue());
CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder()
.shortTag("id", (short) entry.getBedrockId()) .shortTag("id", (short) entry.getBedrockId())
.byteTag("Count", (byte) tag.get("Count").getValue()) .byteTag("Count", (byte) tag.get("Count").getValue())

View File

@ -4,12 +4,11 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
public class BlockEntityUtils { public class BlockEntityUtils {
private static final BlockEntityTranslator EMPTY_TRANSLATOR = Translators.getBlockEntityTranslators().get("Empty"); private static final BlockEntityTranslator EMPTY_TRANSLATOR = BlockEntityTranslator.BLOCK_ENTITY_TRANSLATORS.get("Empty");
public static String getBedrockBlockEntityId(String id) { public static String getBedrockBlockEntityId(String id) {
// These are the only exceptions when it comes to block entity ids // These are the only exceptions when it comes to block entity ids
@ -39,7 +38,7 @@ public class BlockEntityUtils {
} }
public static BlockEntityTranslator getBlockEntityTranslator(String name) { public static BlockEntityTranslator getBlockEntityTranslator(String name) {
BlockEntityTranslator blockEntityTranslator = Translators.getBlockEntityTranslators().get(name); BlockEntityTranslator blockEntityTranslator = BlockEntityTranslator.BLOCK_ENTITY_TRANSLATORS.get(name);
if (blockEntityTranslator == null) { if (blockEntityTranslator == null) {
return EMPTY_TRANSLATOR; return EMPTY_TRANSLATOR;
} }

View File

@ -32,6 +32,9 @@ import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector2i;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.CompoundTagBuilder;
import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.nbt.stream.NBTOutputStream;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
@ -43,11 +46,12 @@ import org.geysermc.connector.entity.ItemFrameEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockStateValues; import org.geysermc.connector.network.translators.world.block.BlockStateValues;
import org.geysermc.connector.network.translators.world.block.entity.*; import org.geysermc.connector.network.translators.world.block.entity.*;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.network.translators.world.chunk.ChunkPosition; import org.geysermc.connector.network.translators.world.chunk.ChunkPosition;
import org.geysermc.connector.network.translators.world.chunk.ChunkSection; import org.geysermc.connector.network.translators.world.chunk.ChunkSection;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -61,6 +65,23 @@ public class ChunkUtils {
*/ */
public static final Map<Position, BlockState> CACHED_BLOCK_ENTITIES = new HashMap<>(); public static final Map<Position, BlockState> CACHED_BLOCK_ENTITIES = new HashMap<>();
private static final com.nukkitx.nbt.tag.CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag();
public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
static {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
try (NBTOutputStream stream = NbtUtils.createNetworkWriter(outputStream)) {
stream.write(EMPTY_TAG);
}
EMPTY_LEVEL_CHUNK_DATA = outputStream.toByteArray();
}catch (IOException e) {
throw new AssertionError("Unable to generate empty level chunk data");
}
}
public static ChunkData translateToBedrock(Column column) { public static ChunkData translateToBedrock(Column column) {
ChunkData chunkData = new ChunkData(); ChunkData chunkData = new ChunkData();
Chunk[] chunks = column.getChunks(); Chunk[] chunks = column.getChunks();
@ -194,7 +215,7 @@ public class ChunkUtils {
// Since Java stores bed colors/skull information as part of the namespaced ID and Bedrock stores it as a tag // Since Java stores bed colors/skull information as part of the namespaced ID and Bedrock stores it as a tag
// This is the only place I could find that interacts with the Java block state and block updates // This is the only place I could find that interacts with the Java block state and block updates
// Iterates through all block entity translators and determines if the block state needs to be saved // Iterates through all block entity translators and determines if the block state needs to be saved
for (RequiresBlockState requiresBlockState : Translators.getRequiresBlockStateMap()) { for (RequiresBlockState requiresBlockState : BlockEntityTranslator.REQUIRES_BLOCK_STATE_LIST) {
if (requiresBlockState.isBlock(blockState)) { if (requiresBlockState.isBlock(blockState)) {
// Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks // Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks
if (requiresBlockState instanceof BedrockOnlyBlockEntity) { if (requiresBlockState instanceof BedrockOnlyBlockEntity) {
@ -217,7 +238,7 @@ public class ChunkUtils {
data.setChunkX(chunkX + x); data.setChunkX(chunkX + x);
data.setChunkZ(chunkZ + z); data.setChunkZ(chunkZ + z);
data.setSubChunksLength(0); data.setSubChunksLength(0);
data.setData(Translators.EMPTY_LEVEL_CHUNK_DATA); data.setData(EMPTY_LEVEL_CHUNK_DATA);
data.setCachingEnabled(false); data.setCachingEnabled(false);
session.sendUpstreamPacket(data); session.sendUpstreamPacket(data);

View File

@ -125,4 +125,18 @@ public class FileUtils {
public static void writeFile(String name, char[] data) throws IOException { public static void writeFile(String name, char[] data) throws IOException {
writeFile(new File(name), data); writeFile(new File(name), data);
} }
/**
* Get an InputStream for the given resource path, throws AssertionError if resource is not found
*
* @param resource Resource to get
* @return InputStream of the given resource
*/
public static InputStream getResource(String resource) {
InputStream stream = FileUtils.class.getClassLoader().getResourceAsStream(resource);
if (stream == null) {
throw new AssertionError("Unable to find resource: " + resource);
}
return stream;
}
} }

View File

@ -36,9 +36,10 @@ import org.geysermc.common.ChatColor;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.DoubleChestInventoryTranslator; import org.geysermc.connector.network.translators.inventory.DoubleChestInventoryTranslator;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemRegistry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import java.util.Collections; import java.util.Collections;
import java.util.Objects; import java.util.Objects;
@ -48,7 +49,7 @@ public class InventoryUtils {
public static final ItemStack REFRESH_ITEM = new ItemStack(1, 127, new CompoundTag("")); //TODO: stop using this public static final ItemStack REFRESH_ITEM = new ItemStack(1, 127, new CompoundTag("")); //TODO: stop using this
public static void openInventory(GeyserSession session, Inventory inventory) { public static void openInventory(GeyserSession session, Inventory inventory) {
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType()); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
if (translator != null) { if (translator != null) {
session.getInventoryCache().setOpenInventory(inventory); session.getInventoryCache().setOpenInventory(inventory);
translator.prepareInventory(session, inventory); translator.prepareInventory(session, inventory);
@ -69,14 +70,14 @@ public class InventoryUtils {
if (windowId != 0) { if (windowId != 0) {
Inventory inventory = session.getInventoryCache().getInventories().get(windowId); Inventory inventory = session.getInventoryCache().getInventories().get(windowId);
if (inventory != null) { if (inventory != null) {
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType()); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
translator.closeInventory(session, inventory); translator.closeInventory(session, inventory);
session.getInventoryCache().uncacheInventory(windowId); session.getInventoryCache().uncacheInventory(windowId);
session.getInventoryCache().setOpenInventory(null); session.getInventoryCache().setOpenInventory(null);
} }
} else { } else {
Inventory inventory = session.getInventory(); Inventory inventory = session.getInventory();
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType()); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
translator.updateInventory(session, inventory); translator.updateInventory(session, inventory);
} }
session.setCraftSlot(0); session.setCraftSlot(0);
@ -87,7 +88,7 @@ public class InventoryUtils {
InventorySlotPacket cursorPacket = new InventorySlotPacket(); InventorySlotPacket cursorPacket = new InventorySlotPacket();
cursorPacket.setContainerId(ContainerId.CURSOR); cursorPacket.setContainerId(ContainerId.CURSOR);
cursorPacket.setSlot(0); cursorPacket.setSlot(0);
cursorPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, session.getInventory().getCursor())); cursorPacket.setItem(ItemTranslator.translateToBedrock(session.getInventory().getCursor()));
session.sendUpstreamPacket(cursorPacket); session.sendUpstreamPacket(cursorPacket);
} }
@ -115,6 +116,6 @@ public class InventoryUtils {
display.listTag("Lore", StringTag.class, Collections.singletonList(new StringTag("", ChatColor.RESET + ChatColor.DARK_PURPLE + description))); display.listTag("Lore", StringTag.class, Collections.singletonList(new StringTag("", ChatColor.RESET + ChatColor.DARK_PURPLE + description)));
root.tag(display.build("display")); root.tag(display.build("display"));
return ItemData.of(Toolbox.ITEM_ENTRIES.get(Toolbox.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.buildRootTag()); return ItemData.of(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.buildRootTag());
} }
} }

View File

@ -50,77 +50,4 @@ public class ItemUtils {
} }
return 0; return 0;
} }
/**
* Convert a list of patterns from Java nbt to Bedrock nbt
*
* @param patterns The patterns to convert
* @return The new converted patterns
*/
public static com.nukkitx.nbt.tag.ListTag convertBannerPattern(ListTag patterns) {
List<com.nukkitx.nbt.tag.CompoundTag> tagsList = new ArrayList<>();
for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) {
com.nukkitx.nbt.tag.CompoundTag newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag);
if (newPatternTag != null) {
tagsList.add(newPatternTag);
}
}
return new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList);
}
/**
* Convert the Java edition banner pattern nbt to Bedrock edition, null if the pattern doesn't exist
*
* @param pattern Java edition pattern nbt
* @return The Bedrock edition format pattern nbt
*/
public static com.nukkitx.nbt.tag.CompoundTag getBedrockBannerPattern(CompoundTag pattern) {
String patternName = (String) pattern.get("Pattern").getValue();
// Return null if its the globe pattern as it doesn't exist on bedrock
if (patternName.equals("glb")) {
return null;
}
return CompoundTagBuilder.builder()
.intTag("Color", 15 - (int) pattern.get("Color").getValue())
.stringTag("Pattern", (String) pattern.get("Pattern").getValue())
.stringTag("Pattern", patternName)
.buildRootTag();
}
/**
* Convert a list of patterns from Bedrock nbt to Java nbt
*
* @param patterns The patterns to convert
* @return The new converted patterns
*/
public static ListTag convertBannerPattern(com.nukkitx.nbt.tag.ListTag patterns) {
List<Tag> tagsList = new ArrayList<>();
for (Object patternTag : patterns.getValue()) {
CompoundTag newPatternTag = getJavaBannerPattern((com.nukkitx.nbt.tag.CompoundTag) patternTag);
if (newPatternTag != null) {
tagsList.add(newPatternTag);
}
}
return new ListTag("Patterns", tagsList);
}
/**
* Convert the Bedrock edition banner pattern nbt to Java edition
*
* @param pattern Bedorck edition pattern nbt
* @return The Java edition format pattern nbt
*/
public static CompoundTag getJavaBannerPattern(com.nukkitx.nbt.tag.CompoundTag pattern) {
String patternName = (String) pattern.get("Pattern").getValue();
Map<String, Tag> tags = new HashMap<>();
tags.put("Color", new IntTag("Color", 15 - pattern.getInt("Color")));
tags.put("Pattern", new StringTag("Pattern", pattern.getString("Pattern")));
return new CompoundTag("", tags);
}
} }

View File

@ -63,7 +63,7 @@ public class LocaleUtils {
private static void generateAssetCache() { private static void generateAssetCache() {
try { try {
// Get the version manifest from Mojang // Get the version manifest from Mojang
VersionManifest versionManifest = Toolbox.JSON_MAPPER.readValue(WebUtils.getBody("https://launchermeta.mojang.com/mc/game/version_manifest.json"), VersionManifest.class); VersionManifest versionManifest = GeyserConnector.JSON_MAPPER.readValue(WebUtils.getBody("https://launchermeta.mojang.com/mc/game/version_manifest.json"), VersionManifest.class);
// Get the url for the latest version of the games manifest // Get the url for the latest version of the games manifest
String latestInfoURL = ""; String latestInfoURL = "";
@ -80,7 +80,7 @@ public class LocaleUtils {
} }
// Get the individual version manifest // Get the individual version manifest
VersionInfo versionInfo = Toolbox.JSON_MAPPER.readValue(WebUtils.getBody(latestInfoURL), VersionInfo.class); VersionInfo versionInfo = GeyserConnector.JSON_MAPPER.readValue(WebUtils.getBody(latestInfoURL), VersionInfo.class);
// Get the smallest jar for use when downloading the en_us locale, will be either the server or client // Get the smallest jar for use when downloading the en_us locale, will be either the server or client
int currentSize = Integer.MAX_VALUE; int currentSize = Integer.MAX_VALUE;
@ -92,13 +92,13 @@ public class LocaleUtils {
} }
// Get the assets list // Get the assets list
JsonNode assets = Toolbox.JSON_MAPPER.readTree(WebUtils.getBody(versionInfo.getAssetIndex().getUrl())).get("objects"); JsonNode assets = GeyserConnector.JSON_MAPPER.readTree(WebUtils.getBody(versionInfo.getAssetIndex().getUrl())).get("objects");
// Put each asset into an array for use later // Put each asset into an array for use later
Iterator<Map.Entry<String, JsonNode>> assetIterator = assets.fields(); Iterator<Map.Entry<String, JsonNode>> assetIterator = assets.fields();
while (assetIterator.hasNext()) { while (assetIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = assetIterator.next(); Map.Entry<String, JsonNode> entry = assetIterator.next();
Asset asset = Toolbox.JSON_MAPPER.treeToValue(entry.getValue(), Asset.class); Asset asset = GeyserConnector.JSON_MAPPER.treeToValue(entry.getValue(), Asset.class);
ASSET_MAP.put(entry.getKey(), asset); ASSET_MAP.put(entry.getKey(), asset);
} }
} catch (Exception e) { } catch (Exception e) {
@ -173,7 +173,7 @@ public class LocaleUtils {
// Parse the file as json // Parse the file as json
JsonNode localeObj; JsonNode localeObj;
try { try {
localeObj = Toolbox.JSON_MAPPER.readTree(localeStream); localeObj = GeyserConnector.JSON_MAPPER.readTree(localeStream);
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Unable to load Java edition lang map for " + locale, e); throw new AssertionError("Unable to load Java edition lang map for " + locale, e);
} }

View File

@ -72,7 +72,7 @@ public class SkinProvider {
static { static {
/* Load in the normal ears geometry */ /* Load in the normal ears geometry */
InputStream earsStream = Toolbox.getResource("bedrock/skin/geometry.humanoid.ears.json"); InputStream earsStream = FileUtils.getResource("bedrock/skin/geometry.humanoid.ears.json");
StringBuilder earsDataBuilder = new StringBuilder(); StringBuilder earsDataBuilder = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader(earsStream, Charset.forName(StandardCharsets.UTF_8.name())))) { try (Reader reader = new BufferedReader(new InputStreamReader(earsStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
@ -88,7 +88,7 @@ public class SkinProvider {
/* Load in the slim ears geometry */ /* Load in the slim ears geometry */
earsStream = Toolbox.getResource("bedrock/skin/geometry.humanoid.earsSlim.json"); earsStream = FileUtils.getResource("bedrock/skin/geometry.humanoid.earsSlim.json");
earsDataBuilder = new StringBuilder(); earsDataBuilder = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader(earsStream, Charset.forName(StandardCharsets.UTF_8.name())))) { try (Reader reader = new BufferedReader(new InputStreamReader(earsStream, Charset.forName(StandardCharsets.UTF_8.name())))) {