Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
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.
Dieser Commit ist enthalten in:
Ursprung
7154e1c816
Commit
6b68bbb413
@ -25,6 +25,8 @@
|
||||
|
||||
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.BedrockServer;
|
||||
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.remote.RemoteServer;
|
||||
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.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.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.text.DecimalFormat;
|
||||
@ -55,6 +66,8 @@ import java.util.concurrent.TimeUnit;
|
||||
@Getter
|
||||
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 String NAME = "Geyser";
|
||||
@ -99,8 +112,19 @@ public class GeyserConnector {
|
||||
|
||||
logger.setDebug(config.isDebugMode());
|
||||
|
||||
Toolbox.init();
|
||||
Translators.start();
|
||||
PacketTranslatorRegistry.init();
|
||||
|
||||
/* 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) {
|
||||
DockerCheck.check(bootstrap);
|
||||
|
@ -31,7 +31,7 @@ import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
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 {
|
||||
|
||||
@ -52,7 +52,7 @@ public class AreaEffectCloudEntity extends Entity {
|
||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue());
|
||||
} else if (entityMetadata.getId() == 10) {
|
||||
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) {
|
||||
metadata.put(EntityData.POTION_COLOR, entityMetadata.getValue());
|
||||
}
|
||||
|
@ -51,8 +51,7 @@ import org.geysermc.connector.entity.attribute.AttributeType;
|
||||
import org.geysermc.connector.entity.living.ArmorStandEntity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||
import org.geysermc.connector.utils.AttributeUtils;
|
||||
import org.geysermc.connector.utils.ChunkUtils;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
@ -225,11 +224,11 @@ public class Entity {
|
||||
|
||||
// Shield code
|
||||
if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) {
|
||||
if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) ||
|
||||
(session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).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() == ItemRegistry.SHIELD)) {
|
||||
ClientPlayerUseItemPacket useItemPacket;
|
||||
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);
|
||||
}
|
||||
// Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent
|
||||
|
@ -31,7 +31,7 @@ import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
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 {
|
||||
|
||||
@ -49,7 +49,7 @@ public class ItemEntity extends Entity {
|
||||
itemPacket.setUniqueEntityId(geyserId);
|
||||
itemPacket.setFromFishing(false);
|
||||
itemPacket.getMetadata().putAll(metadata);
|
||||
itemPacket.setItemInHand(Translators.getItemTranslator().translateToBedrock(session, (ItemStack) entityMetadata.getValue()));
|
||||
itemPacket.setItemInHand(ItemTranslator.translateToBedrock((ItemStack) entityMetadata.getValue()));
|
||||
session.sendUpstreamPacket(itemPacket);
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,10 @@ import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
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.ItemRegistry;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -98,12 +98,12 @@ public class ItemFrameEntity extends Entity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) {
|
||||
ItemData itemData = Translators.getItemTranslator().translateToBedrock(session, (ItemStack) entityMetadata.getValue());
|
||||
ItemEntry itemEntry = Translators.getItemTranslator().getItem((ItemStack) entityMetadata.getValue());
|
||||
ItemData itemData = ItemTranslator.translateToBedrock((ItemStack) entityMetadata.getValue());
|
||||
ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
|
||||
CompoundTagBuilder builder = CompoundTag.builder();
|
||||
|
||||
String blockName = "";
|
||||
for (StartGamePacket.ItemEntry startGamePacketItemEntry: Toolbox.ITEMS) {
|
||||
for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
|
||||
if (startGamePacketItemEntry.getId() == (short) itemEntry.getBedrockId()) {
|
||||
blockName = startGamePacketItemEntry.getIdentifier();
|
||||
break;
|
||||
|
@ -31,7 +31,7 @@ import org.geysermc.common.AuthType;
|
||||
import org.geysermc.connector.GeyserConfiguration;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
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;
|
||||
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
@ -41,7 +41,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
}
|
||||
|
||||
private boolean translateAndDefault(BedrockPacket packet) {
|
||||
return Registry.BEDROCK.translate(packet.getClass(), packet, session);
|
||||
return PacketTranslatorRegistry.BEDROCK_TRANSLATOR.translate(packet.getClass(), packet, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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.BedrockClientData;
|
||||
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.utils.ChunkUtils;
|
||||
import org.geysermc.connector.utils.LocaleUtils;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
import org.geysermc.floodgate.util.BedrockData;
|
||||
import org.geysermc.floodgate.util.EncryptionUtil;
|
||||
|
||||
@ -194,16 +196,16 @@ public class GeyserSession implements CommandSender {
|
||||
ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
|
||||
|
||||
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
|
||||
biomeDefinitionListPacket.setTag(Toolbox.BIOMES);
|
||||
biomeDefinitionListPacket.setTag(BiomeTranslator.BIOMES);
|
||||
upstream.sendPacket(biomeDefinitionListPacket);
|
||||
|
||||
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
|
||||
entityPacket.setTag(Toolbox.ENTITY_IDENTIFIERS);
|
||||
entityPacket.setTag(EntityIdentifierRegistry.ENTITY_IDENTIFIERS);
|
||||
upstream.sendPacket(entityPacket);
|
||||
|
||||
InventoryContentPacket creativePacket = new InventoryContentPacket();
|
||||
creativePacket.setContainerId(ContainerId.CREATIVE);
|
||||
creativePacket.setContents(Toolbox.CREATIVE_ITEMS);
|
||||
creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS);
|
||||
upstream.sendPacket(creativePacket);
|
||||
|
||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||
@ -345,7 +347,7 @@ public class GeyserSession implements CommandSender {
|
||||
lastDimPacket = event.getPacket();
|
||||
return;
|
||||
} else if (lastDimPacket != null) {
|
||||
Registry.JAVA.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this);
|
||||
PacketTranslatorRegistry.JAVA_TRANSLATOR.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this);
|
||||
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.setMultiplayerCorrelationId("");
|
||||
startGamePacket.setBlockPalette(BlockTranslator.BLOCKS);
|
||||
startGamePacket.setItemEntries(Toolbox.ITEMS);
|
||||
startGamePacket.setItemEntries(ItemRegistry.ITEMS);
|
||||
startGamePacket.setVanillaVersion("*");
|
||||
// startGamePacket.setMovementServerAuthoritative(true);
|
||||
upstream.sendPacket(startGamePacket);
|
||||
|
@ -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;
|
||||
|
||||
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;
|
||||
|
||||
//Based off of ProtocolSupport's LegacyBiomeData.java https://github.com/ProtocolSupport/ProtocolSupport/blob/b2cad35977f3fcb65bee57b9e14fc9c975f71d32/src/protocolsupport/protocol/typeremapper/legacy/LegacyBiomeData.java
|
||||
//Array index formula by https://wiki.vg/Chunk_Format
|
||||
|
||||
// Based off of ProtocolSupport's LegacyBiomeData.java:
|
||||
// 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 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) {
|
||||
byte[] bedrockData = new byte[256];
|
||||
if(biomeData == null) {
|
||||
if (biomeData == null) {
|
||||
return bedrockData;
|
||||
}
|
||||
|
||||
@ -24,12 +82,12 @@ public class BiomeTranslator {
|
||||
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;
|
||||
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)];
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -35,33 +35,59 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import com.github.steveice10.packetlib.packet.Packet;
|
||||
import com.nukkitx.protocol.bedrock.BedrockPacket;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
public class Registry<T> {
|
||||
private final Map<Class<? extends T>, PacketTranslator<? extends T>> MAP = new HashMap<>();
|
||||
public class PacketTranslatorRegistry<T> {
|
||||
private final Map<Class<? extends T>, PacketTranslator<? extends T>> translators = new HashMap<>();
|
||||
|
||||
public static final Registry<Packet> JAVA = new Registry<>();
|
||||
public static final Registry<BedrockPacket> BEDROCK = new Registry<>();
|
||||
public static final PacketTranslatorRegistry<Packet> JAVA_TRANSLATOR = new PacketTranslatorRegistry<>();
|
||||
public static final PacketTranslatorRegistry<BedrockPacket> BEDROCK_TRANSLATOR = new PacketTranslatorRegistry<>();
|
||||
|
||||
private static final ObjectArrayList<Class<?>> IGNORED_PACKETS = new ObjectArrayList<>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static void registerJava(Class<? extends Packet> targetPacket, PacketTranslator<? extends Packet> translator) {
|
||||
JAVA.MAP.put(targetPacket, translator);
|
||||
private PacketTranslatorRegistry() {
|
||||
}
|
||||
|
||||
public static void registerBedrock(Class<? extends BedrockPacket> targetPacket, PacketTranslator<? extends BedrockPacket> translator) {
|
||||
BEDROCK.MAP.put(targetPacket, translator);
|
||||
public static void init() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <P extends T> boolean translate(Class<? extends P> clazz, P packet, GeyserSession session) {
|
||||
if (!session.getUpstream().isClosed() && !session.isClosed()) {
|
||||
try {
|
||||
if (MAP.containsKey(clazz)) {
|
||||
((PacketTranslator<P>) MAP.get(clazz)).translate(packet, session);
|
||||
if (translators.containsKey(clazz)) {
|
||||
((PacketTranslator<P>) translators.get(clazz)).translate(packet, session);
|
||||
return true;
|
||||
} else {
|
||||
if (!IGNORED_PACKETS.contains(clazz))
|
@ -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
|
||||
}
|
||||
}
|
@ -31,15 +31,13 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientMoveI
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.BlockPickRequestPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerHotbarPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
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.item.ItemTranslator;
|
||||
import org.geysermc.connector.network.translators.Translators;
|
||||
|
||||
@Translator(packet = BlockPickRequestPacket.class)
|
||||
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];
|
||||
ItemTranslator itemTranslator = Translators.getItemTranslator();
|
||||
|
||||
// Check hotbar for item
|
||||
for (int i = 36; i < 45; i++) {
|
||||
if (inventory.getItem(i) == null) {
|
||||
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 (!item.getJavaIdentifier().equals(targetIdentifier)) {
|
||||
continue;
|
||||
@ -90,7 +87,7 @@ public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator<Bl
|
||||
if (inventory.getItem(i) == null) {
|
||||
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 (!item.getJavaIdentifier().equals(targetIdentifier)) {
|
||||
continue;
|
||||
|
@ -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.ClientPlayerStatePacket;
|
||||
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)
|
||||
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
|
||||
@ -51,7 +51,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
|
||||
|
||||
switch (packet.getAction()) {
|
||||
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;
|
||||
}
|
||||
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
|
||||
|
@ -49,9 +49,9 @@ import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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.ItemTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||
import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
@ -65,12 +65,12 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
case NORMAL:
|
||||
Inventory inventory = session.getInventoryCache().getOpenInventory();
|
||||
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;
|
||||
case INVENTORY_MISMATCH:
|
||||
Inventory inv = session.getInventoryCache().getOpenInventory();
|
||||
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);
|
||||
break;
|
||||
case ITEM_USE:
|
||||
@ -99,7 +99,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
session.sendDownstreamPacket(blockPacket);
|
||||
|
||||
// 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);
|
||||
session.sendDownstreamPacket(itemPacket);
|
||||
}
|
||||
@ -126,7 +126,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
blockPos = blockPos.add(1, 0, 0);
|
||||
break;
|
||||
}
|
||||
ItemEntry handItem = Translators.getItemTranslator().getItem(packet.getItemInHand());
|
||||
ItemEntry handItem = ItemRegistry.getItem(packet.getItemInHand());
|
||||
if (handItem.isBlock()) {
|
||||
session.setLastBlockPlacePosition(blockPos);
|
||||
session.setLastBlockPlacedId(handItem.getJavaIdentifier());
|
||||
@ -136,7 +136,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
break;
|
||||
case 1:
|
||||
ItemStack shieldSlot = session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36);
|
||||
if (shieldSlot != null && shieldSlot.getId() == ItemTranslator.SHIELD) {
|
||||
if (shieldSlot != null && shieldSlot.getId() == ItemRegistry.SHIELD) {
|
||||
break;
|
||||
} // Handled in Entity.java
|
||||
ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
|
||||
|
@ -21,29 +21,30 @@
|
||||
*
|
||||
* @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.github.steveice10.mc.protocol.data.game.world.particle.ParticleType;
|
||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
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.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
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 Int2ObjectMap<SoundEvent> RECORDS = new Int2ObjectOpenHashMap<>();
|
||||
@ -57,10 +58,10 @@ public class EffectUtils {
|
||||
|
||||
static {
|
||||
/* Load particles */
|
||||
InputStream particleStream = Toolbox.getResource("mappings/particles.json");
|
||||
InputStream particleStream = FileUtils.getResource("mappings/particles.json");
|
||||
JsonNode particleEntries;
|
||||
try {
|
||||
particleEntries = Toolbox.JSON_MAPPER.readTree(particleStream);
|
||||
particleEntries = GeyserConnector.JSON_MAPPER.readTree(particleStream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load particle map", e);
|
||||
}
|
||||
@ -69,10 +70,10 @@ public class EffectUtils {
|
||||
while (particlesIterator.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = particlesIterator.next();
|
||||
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) {
|
||||
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 "
|
||||
+ entry.getKey()
|
||||
+ "=>"
|
||||
@ -85,10 +86,10 @@ public class EffectUtils {
|
||||
}
|
||||
|
||||
/* Load effects */
|
||||
InputStream effectsStream = Toolbox.getResource("mappings/effects.json");
|
||||
InputStream effectsStream = FileUtils.getResource("mappings/effects.json");
|
||||
JsonNode effects;
|
||||
try {
|
||||
effects = Toolbox.JSON_MAPPER.readTree(effectsStream);
|
||||
effects = GeyserConnector.JSON_MAPPER.readTree(effectsStream);
|
||||
} catch (Exception 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) {
|
||||
return particleTypeMap.getOrDefault(type, null);
|
||||
}
|
||||
@ -127,5 +120,4 @@ public class EffectUtils {
|
||||
public static String getParticleString(@NonNull ParticleType type){
|
||||
return particleStringMap.getOrDefault(type, null);
|
||||
}
|
||||
|
||||
}
|
@ -25,15 +25,50 @@
|
||||
|
||||
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 lombok.AllArgsConstructor;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
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 abstract void prepareInventory(GeyserSession session, Inventory inventory);
|
||||
|
@ -36,10 +36,9 @@ import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -60,11 +59,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
ItemData[] contents = new ItemData[36];
|
||||
// Inventory
|
||||
for (int i = 9; i < 36; i++) {
|
||||
contents[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i));
|
||||
contents[i] = ItemTranslator.translateToBedrock(inventory.getItem(i));
|
||||
}
|
||||
// Hotbar
|
||||
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);
|
||||
session.sendUpstreamPacket(inventoryContentPacket);
|
||||
@ -74,7 +73,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
armorContentPacket.setContainerId(ContainerId.ARMOR);
|
||||
contents = new ItemData[4];
|
||||
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);
|
||||
session.sendUpstreamPacket(armorContentPacket);
|
||||
@ -82,7 +81,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
// Offhand
|
||||
InventoryContentPacket offhandPacket = new InventoryContentPacket();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -101,7 +100,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
if (session.getGameMode() == GameMode.CREATIVE) {
|
||||
slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK);
|
||||
}else{
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(i)));
|
||||
}
|
||||
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
@ -126,12 +125,12 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
slotPacket.setContainerId(ContainerId.CURSOR);
|
||||
slotPacket.setSlot(slot + 27);
|
||||
}
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(slot)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(slot)));
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
} else if (slot == 45) {
|
||||
InventoryContentPacket offhandPacket = new InventoryContentPacket();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -202,7 +201,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
if (action.getToItem().getId() == 0) {
|
||||
javaItem = new ItemStack(-1, 0, null);
|
||||
} else {
|
||||
javaItem = Translators.getItemTranslator().translateToJava(session, action.getToItem());
|
||||
javaItem = ItemTranslator.translateToJava(action.getToItem());
|
||||
}
|
||||
ClientCreativeInventoryActionPacket creativePacket = new ClientCreativeInventoryActionPacket(javaSlot, javaItem);
|
||||
session.sendDownstreamPacket(creativePacket);
|
||||
@ -210,13 +209,13 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
break;
|
||||
case ContainerId.CURSOR:
|
||||
if (action.getSlot() == 0) {
|
||||
session.getInventory().setCursor(Translators.getItemTranslator().translateToJava(session, action.getToItem()));
|
||||
session.getInventory().setCursor(ItemTranslator.translateToJava(action.getToItem()));
|
||||
}
|
||||
break;
|
||||
case ContainerId.NONE:
|
||||
if (action.getSource().getType() == InventorySource.Type.WORLD_INTERACTION
|
||||
&& 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);
|
||||
session.sendDownstreamPacket(creativeDropPacket);
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ import com.nukkitx.protocol.bedrock.data.InventorySource;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.SlotType;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
|
||||
import java.util.*;
|
||||
@ -61,13 +61,13 @@ public class InventoryActionDataTranslator {
|
||||
worldAction = action;
|
||||
} else if (action.getSource().getContainerId() == ContainerId.CURSOR && action.getSlot() == 0) {
|
||||
cursorAction = action;
|
||||
ItemData translatedCursor = Translators.getItemTranslator().translateToBedrock(session, session.getInventory().getCursor());
|
||||
ItemData translatedCursor = ItemTranslator.translateToBedrock(session.getInventory().getCursor());
|
||||
if (!translatedCursor.equals(action.getFromItem())) {
|
||||
refresh = true;
|
||||
}
|
||||
} else {
|
||||
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())) {
|
||||
refresh = true;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
|
||||
@AllArgsConstructor
|
||||
@ -49,7 +49,7 @@ public class ChestInventoryUpdater extends InventoryUpdater {
|
||||
ItemData[] bedrockItems = new ItemData[paddedSize];
|
||||
for (int i = 0; i < bedrockItems.length; i++) {
|
||||
if (i < translator.size) {
|
||||
bedrockItems[i] = Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i));
|
||||
bedrockItems[i] = ItemTranslator.translateToBedrock(inventory.getItem(i));
|
||||
} else {
|
||||
bedrockItems[i] = UNUSUABLE_SPACE_BLOCK;
|
||||
}
|
||||
@ -69,7 +69,7 @@ public class ChestInventoryUpdater extends InventoryUpdater {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(inventory.getId());
|
||||
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
return true;
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.item.ItemTranslator;
|
||||
|
||||
public class ContainerInventoryUpdater extends InventoryUpdater {
|
||||
@Override
|
||||
@ -40,7 +40,7 @@ public class ContainerInventoryUpdater extends InventoryUpdater {
|
||||
|
||||
ItemData[] bedrockItems = new ItemData[translator.size];
|
||||
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();
|
||||
@ -57,7 +57,7 @@ public class ContainerInventoryUpdater extends InventoryUpdater {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(inventory.getId());
|
||||
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
return true;
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ import com.nukkitx.protocol.bedrock.data.ContainerId;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.item.ItemTranslator;
|
||||
|
||||
public class CursorInventoryUpdater extends InventoryUpdater {
|
||||
@Override
|
||||
@ -44,7 +44,7 @@ public class CursorInventoryUpdater extends InventoryUpdater {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(ContainerId.CURSOR);
|
||||
slotPacket.setSlot(bedrockSlot);
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(i)));
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@ public class CursorInventoryUpdater extends InventoryUpdater {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(ContainerId.CURSOR);
|
||||
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
return true;
|
||||
}
|
||||
|
@ -31,15 +31,15 @@ import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.item.ItemTranslator;
|
||||
|
||||
public abstract class InventoryUpdater {
|
||||
public void updateInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
|
||||
ItemData[] bedrockItems = new ItemData[36];
|
||||
for (int i = 0; i < 36; i++) {
|
||||
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();
|
||||
contentPacket.setContainerId(ContainerId.INVENTORY);
|
||||
@ -52,7 +52,7 @@ public abstract class InventoryUpdater {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(ContainerId.INVENTORY);
|
||||
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(javaSlot)));
|
||||
slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(javaSlot)));
|
||||
session.sendUpstreamPacket(slotPacket);
|
||||
return true;
|
||||
}
|
||||
|
@ -21,71 +21,65 @@
|
||||
*
|
||||
* @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.databind.DeserializationFeature;
|
||||
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.stream.NBTInputStream;
|
||||
import com.nukkitx.nbt.tag.CompoundTag;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.network.translators.item.ToolItemEntry;
|
||||
import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
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 List<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>();
|
||||
|
||||
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 void init() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
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 */
|
||||
InputStream stream = getResource("bedrock/items.json");
|
||||
InputStream stream = FileUtils.getResource("bedrock/items.json");
|
||||
|
||||
TypeReference<List<JsonNode>> itemEntriesType = new TypeReference<List<JsonNode>>() {
|
||||
};
|
||||
|
||||
List<JsonNode> itemEntries;
|
||||
try {
|
||||
itemEntries = JSON_MAPPER.readValue(stream, itemEntriesType);
|
||||
itemEntries = GeyserConnector.JSON_MAPPER.readValue(stream, itemEntriesType);
|
||||
} catch (Exception 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()));
|
||||
}
|
||||
|
||||
stream = getResource("mappings/items.json");
|
||||
stream = FileUtils.getResource("mappings/items.json");
|
||||
|
||||
JsonNode items;
|
||||
try {
|
||||
items = JSON_MAPPER.readTree(stream);
|
||||
items = GeyserConnector.JSON_MAPPER.readTree(stream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
||||
}
|
||||
@ -139,22 +133,12 @@ public class Toolbox {
|
||||
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 */
|
||||
stream = getResource("bedrock/creative_items.json");
|
||||
stream = FileUtils.getResource("bedrock/creative_items.json");
|
||||
|
||||
JsonNode creativeItemEntries;
|
||||
try {
|
||||
creativeItemEntries = JSON_MAPPER.readTree(stream).get("items");
|
||||
creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items");
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load creative items", e);
|
||||
}
|
||||
@ -179,33 +163,51 @@ public class Toolbox {
|
||||
}
|
||||
}
|
||||
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
|
||||
* @return InputStream of the given resource
|
||||
* @param stack the item stack
|
||||
* @return an item entry from the given item stack
|
||||
*/
|
||||
public static InputStream getResource(String resource) {
|
||||
InputStream stream = Toolbox.class.getClassLoader().getResourceAsStream(resource);
|
||||
if (stream == null) {
|
||||
throw new AssertionError("Unable to find resource: " + resource);
|
||||
}
|
||||
return stream;
|
||||
public static ItemEntry getItem(ItemStack stack) {
|
||||
return ITEM_ENTRIES.get(stack.getId());
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
@ -21,37 +21,43 @@
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.network.translators.item;
|
||||
|
||||
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 it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.*;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
import org.geysermc.connector.network.translators.ItemRemapper;
|
||||
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;
|
||||
|
||||
public class ItemTranslator {
|
||||
public abstract class ItemTranslator {
|
||||
|
||||
private Int2ObjectMap<ItemStackTranslator> itemTranslators = new Int2ObjectOpenHashMap();
|
||||
private List<NbtItemStackTranslator> nbtItemTranslators;
|
||||
private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>();
|
||||
private static final Int2ObjectMap<ItemTranslator> ITEM_STACK_TRANSLATORS = new Int2ObjectOpenHashMap<>();
|
||||
private static final List<NbtItemStackTranslator> NBT_TRANSLATORS;
|
||||
|
||||
// Shield ID, used in Entity.java
|
||||
public static final int SHIELD = 829;
|
||||
// Boat ID, used in BedrockInventoryTransactionTranslator.java
|
||||
public static final int BOAT = 333;
|
||||
protected ItemTranslator() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
public static void init() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
static {
|
||||
/* Load item translators */
|
||||
Reflections ref = new Reflections("org.geysermc.connector.network.translators.item");
|
||||
|
||||
Map<NbtItemStackTranslator, Integer> loadedNbtItemTranslators = new HashMap<>();
|
||||
@ -66,34 +72,33 @@ public class ItemTranslator {
|
||||
loadedNbtItemTranslators.put(nbtItemTranslator, priority);
|
||||
continue;
|
||||
}
|
||||
ItemStackTranslator itemStackTranslator = (ItemStackTranslator) clazz.newInstance();
|
||||
ItemTranslator itemStackTranslator = (ItemTranslator) clazz.newInstance();
|
||||
List<ItemEntry> appliedItems = itemStackTranslator.getAppliedItems();
|
||||
for (ItemEntry item : appliedItems) {
|
||||
ItemStackTranslator registered = itemTranslators.get(item.getJavaId());
|
||||
ItemTranslator registered = ITEM_STACK_TRANSLATORS.get(item.getJavaId());
|
||||
if (registered != null) {
|
||||
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());
|
||||
continue;
|
||||
}
|
||||
itemTranslators.put(item.getJavaId(), itemStackTranslator);
|
||||
ITEM_STACK_TRANSLATORS.put(item.getJavaId(), itemStackTranslator);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + ".");
|
||||
}
|
||||
}
|
||||
|
||||
nbtItemTranslators = loadedNbtItemTranslators.keySet().stream()
|
||||
.sorted(Comparator.comparingInt(value -> loadedNbtItemTranslators.get(value))).collect(Collectors.toList());
|
||||
NBT_TRANSLATORS = loadedNbtItemTranslators.keySet().stream().sorted(Comparator.comparingInt(loadedNbtItemTranslators::get)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public ItemStack translateToJava(GeyserSession session, ItemData data) {
|
||||
public static ItemStack translateToJava(ItemData data) {
|
||||
if (data == null) {
|
||||
return new ItemStack(0);
|
||||
}
|
||||
ItemEntry javaItem = getItem(data);
|
||||
ItemEntry javaItem = ItemRegistry.getItem(data);
|
||||
|
||||
ItemStack itemStack;
|
||||
ItemStackTranslator itemStackTranslator = itemTranslators.get(javaItem.getJavaId());
|
||||
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(javaItem.getJavaId());
|
||||
if (itemStackTranslator != null) {
|
||||
itemStack = itemStackTranslator.translateToJava(data, javaItem);
|
||||
} else {
|
||||
@ -101,7 +106,7 @@ public class ItemTranslator {
|
||||
}
|
||||
|
||||
if (itemStack != null && itemStack.getNbt() != null) {
|
||||
for (NbtItemStackTranslator translator : nbtItemTranslators) {
|
||||
for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
|
||||
if (translator.acceptItem(javaItem)) {
|
||||
translator.translateToJava(itemStack.getNbt(), javaItem);
|
||||
}
|
||||
@ -110,24 +115,24 @@ public class ItemTranslator {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public ItemData translateToBedrock(GeyserSession session, ItemStack stack) {
|
||||
public static ItemData translateToBedrock(ItemStack stack) {
|
||||
if (stack == null) {
|
||||
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);
|
||||
|
||||
if (itemStack.getNbt() != null) {
|
||||
for (NbtItemStackTranslator translator : nbtItemTranslators) {
|
||||
for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
|
||||
if (translator.acceptItem(bedrockItem)) {
|
||||
translator.translateToBedrock(itemStack.getNbt(), bedrockItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemStackTranslator itemStackTranslator = itemTranslators.get(bedrockItem.getJavaId());
|
||||
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
|
||||
if (itemStackTranslator != null) {
|
||||
return itemStackTranslator.translateToBedrock(itemStack, bedrockItem);
|
||||
} else {
|
||||
@ -135,37 +140,216 @@ public class ItemTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
public ItemEntry getItem(ItemStack stack) {
|
||||
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() {
|
||||
private static final ItemTranslator DEFAULT_TRANSLATOR = new ItemTranslator() {
|
||||
@Override
|
||||
public List<ItemEntry> getAppliedItems() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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.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.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
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.utils.ItemUtils;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ItemRemapper
|
||||
public class BannerTranslator extends ItemStackTranslator {
|
||||
public class BannerTranslator extends ItemTranslator {
|
||||
|
||||
private List<ItemEntry> appliedItems;
|
||||
|
||||
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
|
||||
@ -59,7 +64,7 @@ public class BannerTranslator extends ItemStackTranslator {
|
||||
ListTag patterns = blockEntityTag.get("Patterns");
|
||||
|
||||
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());
|
||||
}
|
||||
@ -75,10 +80,10 @@ public class BannerTranslator extends ItemStackTranslator {
|
||||
|
||||
com.nukkitx.nbt.tag.CompoundTag nbtTag = itemData.getTag();
|
||||
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");
|
||||
blockEntityTag.put(ItemUtils.convertBannerPattern(patterns));
|
||||
blockEntityTag.put(convertBannerPattern(patterns));
|
||||
|
||||
itemStack.getNbt().put(blockEntityTag);
|
||||
}
|
||||
@ -90,4 +95,73 @@ public class BannerTranslator extends ItemStackTranslator {
|
||||
public List<ItemEntry> getAppliedItems() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -30,22 +30,22 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
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.item.ItemEntry;
|
||||
import org.geysermc.connector.network.translators.item.Potion;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ItemRemapper
|
||||
public class PotionTranslator extends ItemStackTranslator {
|
||||
public class PotionTranslator extends ItemTranslator {
|
||||
|
||||
private List<ItemEntry> appliedItems;
|
||||
|
||||
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
|
||||
|
@ -34,7 +34,7 @@ import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
||||
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.utils.MessageUtils;
|
||||
|
||||
|
@ -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.Tag;
|
||||
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.utils.MessageUtils;
|
||||
|
||||
|
@ -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.StringTag;
|
||||
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;
|
||||
|
||||
@ItemRemapper
|
||||
|
@ -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.Tag;
|
||||
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;
|
||||
|
||||
@ItemRemapper(priority = 1)
|
||||
|
@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt;
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
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.ItemEntry;
|
||||
|
||||
|
@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
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.utils.FireworkColor;
|
||||
|
||||
|
@ -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.IntTag;
|
||||
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;
|
||||
|
||||
@ItemRemapper
|
||||
|
@ -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.StringTag;
|
||||
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;
|
||||
|
||||
@ItemRemapper
|
||||
|
@ -42,9 +42,9 @@ import lombok.EqualsAndHashCode;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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.utils.Toolbox;
|
||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@ -64,7 +64,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||
switch (recipe.getType()) {
|
||||
case CRAFTING_SHAPELESS: {
|
||||
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
|
||||
ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
|
||||
for (ItemData[] inputs : inputCombinations) {
|
||||
@ -76,7 +76,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||
}
|
||||
case CRAFTING_SHAPED: {
|
||||
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
|
||||
ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
|
||||
for (ItemData[] inputs : inputCombinations) {
|
||||
@ -103,7 +103,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||
}
|
||||
Ingredient ingredient = ingredients[i];
|
||||
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())));
|
||||
Set<ItemData> optionSet = new HashSet<>(groupedByIds.size());
|
||||
for (Map.Entry<GroupedItem, List<ItemData>> entry : groupedByIds.entrySet()) {
|
||||
@ -111,7 +111,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||
GroupedItem groupedItem = entry.getKey();
|
||||
int idCount = 0;
|
||||
//not optimal
|
||||
for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.values()) {
|
||||
for (ItemEntry itemEntry : ItemRegistry.ITEM_ENTRIES.values()) {
|
||||
if (itemEntry.getBedrockId() == groupedItem.id) {
|
||||
idCount++;
|
||||
}
|
||||
@ -136,7 +136,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||
ItemData[] translatedItems = new ItemData[ingredients.length];
|
||||
for (int i = 0; i < ingredients.length; i++) {
|
||||
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 {
|
||||
translatedItems[i] = ItemData.AIR;
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ import org.geysermc.connector.entity.LivingEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
|
||||
@Translator(packet = ServerEntityEquipmentPacket.class)
|
||||
public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntityEquipmentPacket> {
|
||||
@ -55,7 +55,7 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntity
|
||||
}
|
||||
|
||||
LivingEntity livingEntity = (LivingEntity) entity;
|
||||
ItemData item = Translators.getItemTranslator().translateToBedrock(session, packet.getItem());
|
||||
ItemData item = ItemTranslator.translateToBedrock(packet.getItem());
|
||||
switch (packet.getSlot()) {
|
||||
case HELMET:
|
||||
livingEntity.setHelmet(item);
|
||||
|
@ -35,7 +35,7 @@ import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||
import org.geysermc.connector.inventory.PlayerInventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
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.item.ItemEntry;
|
||||
import org.geysermc.connector.utils.BlockUtils;
|
||||
@ -76,7 +76,7 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayer
|
||||
ItemEntry itemEntry = null;
|
||||
CompoundTag nbtData = new CompoundTag("");
|
||||
if (item != null) {
|
||||
itemEntry = Translators.getItemTranslator().getItem(item);
|
||||
itemEntry = ItemRegistry.getItem(item);
|
||||
nbtData = item.getNbt();
|
||||
}
|
||||
double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session) * 20);
|
||||
|
@ -32,7 +32,7 @@ import com.nukkitx.protocol.bedrock.packet.StopSoundPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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)
|
||||
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());
|
||||
return;
|
||||
}
|
||||
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound);
|
||||
SoundRegistry.SoundMapping soundMapping = SoundRegistry.fromJava(packetSound);
|
||||
session.getConnector().getLogger()
|
||||
.debug("[StopSound] Sound mapping " + packetSound + " -> "
|
||||
+ soundMapping + (soundMapping == null ? "[not found]" : "")
|
||||
|
@ -35,7 +35,6 @@ import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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.utils.InventoryUtils;
|
||||
|
||||
@ -49,14 +48,14 @@ public class JavaOpenWindowTranslator extends PacketTranslator<ServerOpenWindowP
|
||||
if (packet.getWindowId() == 0) {
|
||||
return;
|
||||
}
|
||||
InventoryTranslator newTranslator = Translators.getInventoryTranslators().get(packet.getType());
|
||||
InventoryTranslator newTranslator = InventoryTranslator.INVENTORY_TRANSLATORS.get(packet.getType());
|
||||
Inventory openInventory = session.getInventoryCache().getOpenInventory();
|
||||
if (newTranslator == null) {
|
||||
if (openInventory != null) {
|
||||
ContainerClosePacket closePacket = new ContainerClosePacket();
|
||||
closePacket.setWindowId((byte)openInventory.getId());
|
||||
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());
|
||||
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);
|
||||
session.getInventoryCache().cacheInventory(newInventory);
|
||||
if (openInventory != null) {
|
||||
InventoryTranslator openTranslator = Translators.getInventoryTranslators().get(openInventory.getWindowType());
|
||||
InventoryTranslator openTranslator = InventoryTranslator.INVENTORY_TRANSLATORS.get(openInventory.getWindowType());
|
||||
if (!openTranslator.getClass().equals(newTranslator.getClass())) {
|
||||
InventoryUtils.closeInventory(session, openInventory.getId());
|
||||
GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> InventoryUtils.openInventory(session, newInventory), 500, TimeUnit.MILLISECONDS);
|
||||
|
@ -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.network.session.GeyserSession;
|
||||
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.Translator;
|
||||
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))
|
||||
return;
|
||||
|
||||
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType());
|
||||
InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
|
||||
if (translator != null) {
|
||||
inventory.setItem(packet.getSlot(), packet.getItem());
|
||||
translator.updateSlot(session, inventory, packet.getSlot());
|
||||
|
@ -30,7 +30,6 @@ import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.network.translators.Translators;
|
||||
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -50,7 +49,7 @@ public class JavaWindowItemsTranslator extends PacketTranslator<ServerWindowItem
|
||||
inventory.setItems(packet.getItems());
|
||||
}
|
||||
|
||||
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType());
|
||||
InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
|
||||
if (translator != null) {
|
||||
translator.updateInventory(session, inventory);
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.network.translators.Translators;
|
||||
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
||||
|
||||
@Translator(packet = ServerWindowPropertyPacket.class)
|
||||
@ -42,7 +41,7 @@ public class JavaWindowPropertyTranslator extends PacketTranslator<ServerWindowP
|
||||
if (inventory == null || (packet.getWindowId() != 0 && inventory.getWindowType() == null))
|
||||
return;
|
||||
|
||||
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType());
|
||||
InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
|
||||
if (translator != null) {
|
||||
translator.updateProperty(session, inventory, packet.getRawProperty(), packet.getValue());
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
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)
|
||||
public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayBuiltinSoundPacket> {
|
||||
@ -44,7 +44,7 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
|
||||
public void translate(ServerPlayBuiltinSoundPacket packet, GeyserSession session) {
|
||||
String packetSound = packet.getSound().getName();
|
||||
|
||||
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound);
|
||||
SoundRegistry.SoundMapping soundMapping = SoundRegistry.fromJava(packetSound);
|
||||
if (soundMapping == null) {
|
||||
session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " not found - " + packet.toString());
|
||||
return;
|
||||
@ -59,12 +59,12 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
|
||||
return;
|
||||
}
|
||||
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
|
||||
SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock());
|
||||
SoundEvent sound = SoundRegistry.toSoundEvent(soundMapping.getBedrock());
|
||||
if (sound == null) {
|
||||
sound = SoundUtils.toSoundEvent(soundMapping.getBedrock());
|
||||
sound = SoundRegistry.toSoundEvent(soundMapping.getBedrock());
|
||||
}
|
||||
if (sound == null) {
|
||||
sound = SoundUtils.toSoundEvent(packetSound);
|
||||
sound = SoundRegistry.toSoundEvent(packetSound);
|
||||
}
|
||||
if (sound == null) {
|
||||
session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket
|
||||
|
@ -40,7 +40,7 @@ import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
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 java.util.ArrayList;
|
||||
@ -55,7 +55,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
|
||||
// Some things here are particles, others are not
|
||||
if (packet.getEffect() instanceof ParticleEffect) {
|
||||
ParticleEffect particleEffect = (ParticleEffect) packet.getEffect();
|
||||
Effect geyserEffect = EffectUtils.EFFECTS.get(particleEffect.name());
|
||||
Effect geyserEffect = EffectRegistry.EFFECTS.get(particleEffect.name());
|
||||
if (geyserEffect != null) {
|
||||
String name = geyserEffect.getBedrockName();
|
||||
effect.setType(LevelEventType.valueOf(name));
|
||||
@ -119,7 +119,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
|
||||
session.sendUpstreamPacket(effect);
|
||||
} else if (packet.getEffect() instanceof SoundEffect) {
|
||||
SoundEffect soundEffect = (SoundEffect) packet.getEffect();
|
||||
Effect geyserEffect = EffectUtils.EFFECTS.get(soundEffect.name());
|
||||
Effect geyserEffect = EffectRegistry.EFFECTS.get(soundEffect.name());
|
||||
if (geyserEffect != null) {
|
||||
// Some events are LevelEventTypes, some are SoundEvents.
|
||||
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
|
||||
if (geyserEffect.getJavaName().equals("RECORD")) {
|
||||
RecordEffectData recordEffectData = (RecordEffectData) packet.getData();
|
||||
soundEvent.setSound(EffectUtils.RECORDS.get(recordEffectData.getRecordId()));
|
||||
if (EffectUtils.RECORDS.get(recordEffectData.getRecordId()) != SoundEvent.STOP_RECORD) {
|
||||
soundEvent.setSound(EffectRegistry.RECORDS.get(recordEffectData.getRecordId()));
|
||||
if (EffectRegistry.RECORDS.get(recordEffectData.getRecordId()) != SoundEvent.STOP_RECORD) {
|
||||
// Send text packet as it seems to be handled in Java Edition client-side.
|
||||
TextPacket textPacket = new TextPacket();
|
||||
textPacket.setType(TextPacket.Type.JUKEBOX_POPUP);
|
||||
@ -140,7 +140,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
|
||||
textPacket.setSourceName(null);
|
||||
textPacket.setMessage("record.nowPlaying");
|
||||
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()));
|
||||
textPacket.setParameters(params);
|
||||
session.sendUpstreamPacket(textPacket);
|
||||
|
@ -34,7 +34,7 @@ import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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)
|
||||
public class JavaPlayerPlaySoundTranslator extends PacketTranslator<ServerPlaySoundPacket> {
|
||||
@ -51,7 +51,7 @@ public class JavaPlayerPlaySoundTranslator extends PacketTranslator<ServerPlaySo
|
||||
return;
|
||||
}
|
||||
|
||||
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound.replace("minecraft:", ""));
|
||||
SoundRegistry.SoundMapping soundMapping = SoundRegistry.fromJava(packetSound.replace("minecraft:", ""));
|
||||
String playsound;
|
||||
if(soundMapping == null || soundMapping.getPlaysound() == null) {
|
||||
// no mapping
|
||||
|
@ -34,12 +34,12 @@ import com.nukkitx.protocol.bedrock.packet.SpawnParticleEffectPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
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.utils.EffectUtils;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
||||
|
||||
@Translator(packet = ServerSpawnParticlePacket.class)
|
||||
public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnParticlePacket> {
|
||||
@ -64,7 +64,7 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
|
||||
break;
|
||||
case ITEM:
|
||||
ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack();
|
||||
ItemData bedrockItem = Translators.getItemTranslator().translateToBedrock(session, javaItem);
|
||||
ItemData bedrockItem = ItemTranslator.translateToBedrock(javaItem);
|
||||
int id = bedrockItem.getId();
|
||||
short damage = bedrockItem.getDamage();
|
||||
particle.setType(LevelEventType.PARTICLE_ITEM_BREAK);
|
||||
@ -83,13 +83,13 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
|
||||
session.sendUpstreamPacket(particle);
|
||||
break;
|
||||
default:
|
||||
LevelEventType typeParticle = EffectUtils.getParticleLevelEventType(packet.getParticle().getType());
|
||||
LevelEventType typeParticle = EffectRegistry.getParticleLevelEventType(packet.getParticle().getType());
|
||||
if (typeParticle != null) {
|
||||
particle.setType(typeParticle);
|
||||
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));
|
||||
session.sendUpstreamPacket(particle);
|
||||
} else {
|
||||
String stringParticle = EffectUtils.getParticleString(packet.getParticle().getType());
|
||||
String stringParticle = EffectRegistry.getParticleString(packet.getParticle().getType());
|
||||
if (stringParticle != null) {
|
||||
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
|
||||
stringPacket.setIdentifier(stringParticle);
|
||||
|
@ -29,7 +29,7 @@ package org.geysermc.connector.network.translators.sound;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
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;
|
||||
|
||||
@ -66,7 +66,7 @@ public interface BlockSoundInteractionHandler extends SoundInteractionHandler<St
|
||||
if (itemInHand == null || itemInHand.getId() == 0) {
|
||||
continue;
|
||||
}
|
||||
String handIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
|
||||
String handIdentifier = ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
|
||||
boolean contains = false;
|
||||
for (String itemIdentifier : interactionEntry.getKey().items()) {
|
||||
if (handIdentifier.contains(itemIdentifier)) {
|
||||
|
@ -30,7 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
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;
|
||||
|
||||
@ -67,7 +67,7 @@ public interface EntitySoundInteractionHandler extends SoundInteractionHandler<E
|
||||
if (itemInHand == null || itemInHand.getId() == 0) {
|
||||
continue;
|
||||
}
|
||||
String handIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
|
||||
String handIdentifier = ItemRegistry.getItem(session.getInventory().getItemInHand()).getJavaIdentifier();
|
||||
boolean contains = false;
|
||||
for (String itemIdentifier : interactionEntry.getKey().items()) {
|
||||
if (handIdentifier.contains(itemIdentifier)) {
|
||||
|
@ -21,36 +21,40 @@
|
||||
*
|
||||
* @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.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class SoundUtils {
|
||||
public class SoundRegistry {
|
||||
|
||||
private static final Map<String, SoundMapping> SOUNDS;
|
||||
|
||||
private SoundRegistry() {
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
static {
|
||||
/* Load sound mappings */
|
||||
InputStream stream = Toolbox.getResource("mappings/sounds.json");
|
||||
InputStream stream = FileUtils.getResource("mappings/sounds.json");
|
||||
JsonNode soundsTree;
|
||||
try {
|
||||
soundsTree = Toolbox.JSON_MAPPER.readTree(stream);
|
||||
soundsTree = GeyserConnector.JSON_MAPPER.readTree(stream);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("Unable to load sound mappings", e);
|
||||
}
|
||||
@ -83,6 +87,13 @@ public class SoundUtils {
|
||||
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) {
|
||||
try {
|
||||
return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_"));
|
@ -30,7 +30,7 @@ import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
|
||||
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.SoundHandler;
|
||||
|
||||
@ -39,7 +39,7 @@ public class BucketSoundInteractionHandler implements BlockSoundInteractionHandl
|
||||
|
||||
@Override
|
||||
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();
|
||||
soundEventPacket.setPosition(position);
|
||||
soundEventPacket.setIdentifier(":");
|
||||
|
@ -31,7 +31,7 @@ import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
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.SoundHandler;
|
||||
|
||||
@ -40,7 +40,7 @@ public class MilkCowSoundInteractionHandler implements EntitySoundInteractionHan
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket();
|
||||
|
@ -39,7 +39,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
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 java.io.InputStream;
|
||||
@ -73,7 +73,7 @@ public class BlockTranslator {
|
||||
|
||||
static {
|
||||
/* Load block palette */
|
||||
InputStream stream = Toolbox.getResource("bedrock/runtime_block_states.dat");
|
||||
InputStream stream = FileUtils.getResource("bedrock/runtime_block_states.dat");
|
||||
|
||||
ListTag<CompoundTag> blocksTag;
|
||||
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;
|
||||
try {
|
||||
blocks = Toolbox.JSON_MAPPER.readTree(stream);
|
||||
blocks = GeyserConnector.JSON_MAPPER.readTree(stream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java block mappings", e);
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
import com.nukkitx.nbt.tag.IntTag;
|
||||
import com.nukkitx.nbt.tag.StringTag;
|
||||
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.utils.ItemUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -57,7 +57,7 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement
|
||||
|
||||
if (tag.contains("Patterns")) {
|
||||
ListTag patterns = tag.get("Patterns");
|
||||
tags.add(ItemUtils.convertBannerPattern(patterns));
|
||||
tags.add(BannerTranslator.convertBannerPattern(patterns));
|
||||
}
|
||||
|
||||
if (tag.contains("CustomName")) {
|
||||
|
@ -32,12 +32,49 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
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.reflections.Reflections;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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 CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z);
|
||||
|
@ -30,9 +30,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
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.ItemRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -71,7 +70,7 @@ public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
|
||||
}
|
||||
|
||||
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()
|
||||
.shortTag("id", (short) entry.getBedrockId())
|
||||
.byteTag("Count", (byte) tag.get("Count").getValue())
|
||||
|
@ -4,12 +4,11 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.Translators;
|
||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||
|
||||
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) {
|
||||
// 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) {
|
||||
BlockEntityTranslator blockEntityTranslator = Translators.getBlockEntityTranslators().get(name);
|
||||
BlockEntityTranslator blockEntityTranslator = BlockEntityTranslator.BLOCK_ENTITY_TRANSLATORS.get(name);
|
||||
if (blockEntityTranslator == null) {
|
||||
return EMPTY_TRANSLATOR;
|
||||
}
|
||||
|
@ -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.nukkitx.math.vector.Vector2i;
|
||||
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 it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
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.translators.world.block.BlockStateValues;
|
||||
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.chunk.ChunkPosition;
|
||||
import org.geysermc.connector.network.translators.world.chunk.ChunkSection;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -61,6 +65,23 @@ public class ChunkUtils {
|
||||
*/
|
||||
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) {
|
||||
ChunkData chunkData = new ChunkData();
|
||||
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
|
||||
// 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
|
||||
for (RequiresBlockState requiresBlockState : Translators.getRequiresBlockStateMap()) {
|
||||
for (RequiresBlockState requiresBlockState : BlockEntityTranslator.REQUIRES_BLOCK_STATE_LIST) {
|
||||
if (requiresBlockState.isBlock(blockState)) {
|
||||
// Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks
|
||||
if (requiresBlockState instanceof BedrockOnlyBlockEntity) {
|
||||
@ -217,7 +238,7 @@ public class ChunkUtils {
|
||||
data.setChunkX(chunkX + x);
|
||||
data.setChunkZ(chunkZ + z);
|
||||
data.setSubChunksLength(0);
|
||||
data.setData(Translators.EMPTY_LEVEL_CHUNK_DATA);
|
||||
data.setData(EMPTY_LEVEL_CHUNK_DATA);
|
||||
data.setCachingEnabled(false);
|
||||
session.sendUpstreamPacket(data);
|
||||
|
||||
|
@ -125,4 +125,18 @@ public class FileUtils {
|
||||
public static void writeFile(String name, char[] data) throws IOException {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +36,10 @@ import org.geysermc.common.ChatColor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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.InventoryTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
|
||||
import java.util.Collections;
|
||||
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 void openInventory(GeyserSession session, Inventory inventory) {
|
||||
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType());
|
||||
InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
|
||||
if (translator != null) {
|
||||
session.getInventoryCache().setOpenInventory(inventory);
|
||||
translator.prepareInventory(session, inventory);
|
||||
@ -69,14 +70,14 @@ public class InventoryUtils {
|
||||
if (windowId != 0) {
|
||||
Inventory inventory = session.getInventoryCache().getInventories().get(windowId);
|
||||
if (inventory != null) {
|
||||
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType());
|
||||
InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
|
||||
translator.closeInventory(session, inventory);
|
||||
session.getInventoryCache().uncacheInventory(windowId);
|
||||
session.getInventoryCache().setOpenInventory(null);
|
||||
}
|
||||
} else {
|
||||
Inventory inventory = session.getInventory();
|
||||
InventoryTranslator translator = Translators.getInventoryTranslators().get(inventory.getWindowType());
|
||||
InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType());
|
||||
translator.updateInventory(session, inventory);
|
||||
}
|
||||
session.setCraftSlot(0);
|
||||
@ -87,7 +88,7 @@ public class InventoryUtils {
|
||||
InventorySlotPacket cursorPacket = new InventorySlotPacket();
|
||||
cursorPacket.setContainerId(ContainerId.CURSOR);
|
||||
cursorPacket.setSlot(0);
|
||||
cursorPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, session.getInventory().getCursor()));
|
||||
cursorPacket.setItem(ItemTranslator.translateToBedrock(session.getInventory().getCursor()));
|
||||
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)));
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -50,77 +50,4 @@ public class ItemUtils {
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class LocaleUtils {
|
||||
private static void generateAssetCache() {
|
||||
try {
|
||||
// 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
|
||||
String latestInfoURL = "";
|
||||
@ -80,7 +80,7 @@ public class LocaleUtils {
|
||||
}
|
||||
|
||||
// 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
|
||||
int currentSize = Integer.MAX_VALUE;
|
||||
@ -92,13 +92,13 @@ public class LocaleUtils {
|
||||
}
|
||||
|
||||
// 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
|
||||
Iterator<Map.Entry<String, JsonNode>> assetIterator = assets.fields();
|
||||
while (assetIterator.hasNext()) {
|
||||
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);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -173,7 +173,7 @@ public class LocaleUtils {
|
||||
// Parse the file as json
|
||||
JsonNode localeObj;
|
||||
try {
|
||||
localeObj = Toolbox.JSON_MAPPER.readTree(localeStream);
|
||||
localeObj = GeyserConnector.JSON_MAPPER.readTree(localeStream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load Java edition lang map for " + locale, e);
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class SkinProvider {
|
||||
|
||||
static {
|
||||
/* 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();
|
||||
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 */
|
||||
earsStream = Toolbox.getResource("bedrock/skin/geometry.humanoid.earsSlim.json");
|
||||
earsStream = FileUtils.getResource("bedrock/skin/geometry.humanoid.earsSlim.json");
|
||||
|
||||
earsDataBuilder = new StringBuilder();
|
||||
try (Reader reader = new BufferedReader(new InputStreamReader(earsStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren