forked from GeyserMC/Geyser
		
	Merge branch 'block-entities' into inventory
This commit is contained in:
		
						commit
						418026dbe6
					
				
					 22 changed files with 706 additions and 20 deletions
				
			
		
							
								
								
									
										2
									
								
								.github/workflows/pullrequest.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/pullrequest.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -19,8 +19,6 @@ jobs: | |||
|         uses: actions/setup-java@v1 | ||||
|         with: | ||||
|           java-version: 1.8 | ||||
|       - name: submodules-init | ||||
|         uses: snickerbockers/submodules-init@v4 | ||||
|       - name: Build with Maven | ||||
|         run: mvn -B package | ||||
|       - name: Archive artifacts | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ | |||
| package org.geysermc.connector.entity.living; | ||||
| 
 | ||||
| import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; | ||||
| import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; | ||||
| import com.nukkitx.math.vector.Vector3f; | ||||
| import com.nukkitx.protocol.bedrock.data.EntityData; | ||||
| import com.nukkitx.protocol.bedrock.data.EntityFlag; | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ package org.geysermc.connector.entity.living.animal.horse; | |||
| 
 | ||||
| import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; | ||||
| import com.nukkitx.math.vector.Vector3f; | ||||
| 
 | ||||
| import org.geysermc.connector.entity.living.animal.AnimalEntity; | ||||
| import org.geysermc.connector.entity.type.EntityType; | ||||
| import org.geysermc.connector.network.session.GeyserSession; | ||||
|  |  | |||
|  | @ -45,4 +45,4 @@ public class HorseEntity extends AbstractHorseEntity { | |||
| 
 | ||||
|         super.updateBedrockMetadata(entityMetadata, session); | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -44,6 +44,11 @@ import com.nukkitx.nbt.tag.CompoundTag; | |||
| import com.nukkitx.protocol.bedrock.BedrockServerSession; | ||||
| import com.nukkitx.protocol.bedrock.data.ContainerId; | ||||
| import com.nukkitx.protocol.bedrock.data.GamePublishSetting; | ||||
| import com.nukkitx.protocol.bedrock.packet.AvailableEntityIdentifiersPacket; | ||||
| import com.nukkitx.protocol.bedrock.packet.BiomeDefinitionListPacket; | ||||
| import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; | ||||
| import com.nukkitx.protocol.bedrock.packet.StartGamePacket; | ||||
| import com.nukkitx.protocol.bedrock.packet.TextPacket; | ||||
| import com.nukkitx.protocol.bedrock.data.GameRuleData; | ||||
| import com.nukkitx.protocol.bedrock.data.PlayerPermission; | ||||
| import com.nukkitx.protocol.bedrock.packet.*; | ||||
|  | @ -160,9 +165,9 @@ public class GeyserSession implements CommandSender { | |||
| 
 | ||||
|         ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); | ||||
| 
 | ||||
|         BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket(); | ||||
|         biomeDefinitionListPacket.setTag(Toolbox.BIOMES); | ||||
|         upstream.sendPacket(biomeDefinitionListPacket); | ||||
|         BiomeDefinitionListPacket biomePacket = new BiomeDefinitionListPacket(); | ||||
|         biomePacket.setTag(CompoundTag.EMPTY); | ||||
|         upstream.sendPacket(biomePacket); | ||||
| 
 | ||||
|         AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket(); | ||||
|         entityPacket.setTag(CompoundTag.EMPTY); | ||||
|  |  | |||
|  | @ -49,6 +49,8 @@ import org.geysermc.connector.network.translators.block.BlockTranslator; | |||
| 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.block.entity.*; | ||||
| import org.geysermc.connector.network.translators.inventory.InventoryTranslator; | ||||
| import org.geysermc.connector.network.translators.item.ItemTranslator; | ||||
| import org.geysermc.connector.network.translators.java.*; | ||||
| import org.geysermc.connector.network.translators.java.entity.*; | ||||
|  | @ -74,6 +76,9 @@ public class TranslatorsInit { | |||
|     @Getter | ||||
|     private static Map<WindowType, InventoryTranslator> inventoryTranslators = new HashMap<>(); | ||||
| 
 | ||||
|     @Getter | ||||
|     private static Map<String, BlockEntityTranslator> blockEntityTranslators = new HashMap<>(); | ||||
| 
 | ||||
|     private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); | ||||
|     public static final byte[] EMPTY_LEVEL_CHUNK_DATA; | ||||
| 
 | ||||
|  | @ -143,6 +148,8 @@ public class TranslatorsInit { | |||
|         Registry.registerJava(ServerBlockChangePacket.class, new JavaBlockChangeTranslator()); | ||||
|         Registry.registerJava(ServerMultiBlockChangePacket.class, new JavaMultiBlockChangeTranslator()); | ||||
|         Registry.registerJava(ServerUnloadChunkPacket.class, new JavaUnloadChunkTranslator()); | ||||
|         Registry.registerJava(ServerUpdateTileEntityPacket.class, new JavaUpdateTileEntityTranslator()); | ||||
|         Registry.registerJava(ServerBlockValuePacket.class, new JavaBlockValueTranslator()); | ||||
| 
 | ||||
|         Registry.registerJava(ServerWindowItemsPacket.class, new JavaWindowItemsTranslator()); | ||||
|         Registry.registerJava(ServerOpenWindowPacket.class, new JavaOpenWindowTranslator()); | ||||
|  | @ -170,9 +177,17 @@ public class TranslatorsInit { | |||
|         itemTranslator = new ItemTranslator(); | ||||
|         BlockTranslator.init(); | ||||
| 
 | ||||
|         registerBlockEntityTranslators(); | ||||
|         registerInventoryTranslators(); | ||||
|     } | ||||
| 
 | ||||
|     private static void registerBlockEntityTranslators() { | ||||
|         blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator()); | ||||
|         blockEntityTranslators.put("Sign", new SignBlockEntityTranslator()); | ||||
|         blockEntityTranslators.put("Campfire", new CampfireBlockEntityTranslator()); | ||||
|         blockEntityTranslators.put("Banner", new BannerBlockEntityTranslator()); | ||||
|     } | ||||
| 
 | ||||
|     private static void registerInventoryTranslators() { | ||||
|         inventoryTranslators.put(null, new PlayerInventoryTranslator()); //player inventory | ||||
|         inventoryTranslators.put(WindowType.GENERIC_9X1, new SingleChestInventoryTranslator(9)); | ||||
|  |  | |||
|  | @ -51,6 +51,8 @@ public class BlockTranslator { | |||
|     private static final Map<String, BlockState> JAVA_ID_BLOCK_MAP = new HashMap<>(); | ||||
|     private static final IntSet WATERLOGGED = new IntOpenHashSet(); | ||||
| 
 | ||||
|     private static final Map<BlockState, String> JAVA_ID_TO_BLOCK_ENTITY_MAP = new HashMap<>(); | ||||
| 
 | ||||
|     private static final int BLOCK_STATE_VERSION = 17760256; | ||||
| 
 | ||||
|     static { | ||||
|  | @ -95,6 +97,10 @@ public class BlockTranslator { | |||
| 
 | ||||
|             JAVA_ID_BLOCK_MAP.put(javaId, javaBlockState); | ||||
| 
 | ||||
|             if (javaId.contains("sign[")) { | ||||
|                 JAVA_ID_TO_BLOCK_ENTITY_MAP.put(javaBlockState, javaId); | ||||
|             } | ||||
| 
 | ||||
|             if ("minecraft:water[level=0]".equals(javaId)) { | ||||
|                 waterRuntimeId = bedrockRuntimeId; | ||||
|             } | ||||
|  | @ -183,6 +189,10 @@ public class BlockTranslator { | |||
|         return JAVA_ID_BLOCK_MAP.get(javaId); | ||||
|     } | ||||
| 
 | ||||
|     public static String getBlockEntityString(BlockState javaId) { | ||||
|         return JAVA_ID_TO_BLOCK_ENTITY_MAP.get(javaId); | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isWaterlogged(BlockState state) { | ||||
|         return WATERLOGGED.contains(state.getId()); | ||||
|     } | ||||
|  |  | |||
|  | @ -0,0 +1,77 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.block.entity; | ||||
| 
 | ||||
| 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.StringTag; | ||||
| import com.nukkitx.nbt.tag.Tag; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class BannerBlockEntityTranslator extends BlockEntityTranslator { | ||||
| 
 | ||||
|     @Override | ||||
|     public List<Tag<?>> translateTag(CompoundTag tag) { | ||||
|         List<Tag<?>> tags = new ArrayList<>(); | ||||
|         ListTag patterns = tag.get("Patterns"); | ||||
|         List<com.nukkitx.nbt.tag.CompoundTag> tagsList = new ArrayList<>(); | ||||
|         for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) { | ||||
|             tagsList.add(getPattern((CompoundTag) patternTag)); | ||||
|         } | ||||
|         com.nukkitx.nbt.tag.ListTag<com.nukkitx.nbt.tag.CompoundTag> bedrockPatterns = | ||||
|                 new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); | ||||
|         tags.add(bedrockPatterns); | ||||
| 
 | ||||
|         if (tag.contains("CustomName")) { | ||||
|             tags.add(new StringTag("CustomName", (String) tag.get("CustomName").getValue())); | ||||
|         } | ||||
|         return tags; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { | ||||
|         CompoundTag tag = getConstantJavaTag(javaId, x, y, z); | ||||
|         tag.put(new ListTag("Patterns")); | ||||
|         return tag; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { | ||||
|         CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); | ||||
|         tagBuilder.listTag("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| 
 | ||||
|     protected com.nukkitx.nbt.tag.CompoundTag getPattern(CompoundTag pattern) { | ||||
|         return CompoundTagBuilder.builder() | ||||
|                 .intTag("Color", (int) pattern.get("Color").getValue()) | ||||
|                 .stringTag("Pattern", (String) pattern.get("Pattern").getValue()) | ||||
|                 .buildRootTag(); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,80 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.block.entity; | ||||
| 
 | ||||
| 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 com.nukkitx.nbt.CompoundTagBuilder; | ||||
| import com.nukkitx.nbt.tag.Tag; | ||||
| 
 | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.geysermc.connector.utils.BlockEntityUtils; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| public abstract class BlockEntityTranslator { | ||||
| 
 | ||||
|     public abstract List<Tag<?>> translateTag(CompoundTag tag); | ||||
| 
 | ||||
|     public abstract CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z); | ||||
| 
 | ||||
|     public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z); | ||||
| 
 | ||||
|     public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag) { | ||||
|         int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue())); | ||||
|         int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue())); | ||||
|         int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue())); | ||||
| 
 | ||||
|         CompoundTagBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId( | ||||
|                 String.valueOf(tag.get("id").getValue())), x, y, z).toBuilder(); | ||||
|         translateTag(tag).forEach(tagBuilder::tag); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| 
 | ||||
|     protected CompoundTag getConstantJavaTag(String javaId, int x, int y, int z) { | ||||
|         CompoundTag tag = new CompoundTag(""); | ||||
|         tag.put(new IntTag("x", x)); | ||||
|         tag.put(new IntTag("y", y)); | ||||
|         tag.put(new IntTag("z", z)); | ||||
|         tag.put(new StringTag("id", javaId)); | ||||
|         return tag; | ||||
|     } | ||||
| 
 | ||||
|     protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String bedrockId, int x, int y, int z) { | ||||
|         CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() | ||||
|                 .intTag("x", x) | ||||
|                 .intTag("y", y) | ||||
|                 .intTag("z", z) | ||||
|                 .stringTag("id", bedrockId); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| 
 | ||||
|     @SuppressWarnings("unchecked") | ||||
|     protected <T> T getOrDefault(com.github.steveice10.opennbt.tag.builtin.Tag tag, T defaultValue) { | ||||
|         return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,80 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.block.entity; | ||||
| 
 | ||||
| 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.TranslatorsInit; | ||||
| import org.geysermc.connector.network.translators.item.ItemEntry; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class CampfireBlockEntityTranslator extends BlockEntityTranslator { | ||||
| 
 | ||||
|     @Override | ||||
|     public List<Tag<?>> translateTag(CompoundTag tag) { | ||||
|         List<Tag<?>> tags = new ArrayList<>(); | ||||
|         ListTag items = tag.get("Items"); | ||||
|         int i = 1; | ||||
|         for (com.github.steveice10.opennbt.tag.builtin.Tag itemTag : items.getValue()) { | ||||
|             tags.add(getItem((CompoundTag) itemTag).toBuilder().build("Item" + i)); | ||||
|             i++; | ||||
|         } | ||||
|         return tags; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { | ||||
|         CompoundTag tag = getConstantJavaTag(javaId, x, y, z); | ||||
|         tag.put(new ListTag("Items")); | ||||
|         return tag; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { | ||||
|         CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); | ||||
|         tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item1", new HashMap<>())); | ||||
|         tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item2", new HashMap<>())); | ||||
|         tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item3", new HashMap<>())); | ||||
|         tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item4", new HashMap<>())); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| 
 | ||||
|     protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { | ||||
|         ItemEntry entry = TranslatorsInit.getItemTranslator().getItemEntry((String) tag.get("id").getValue()); | ||||
|         CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() | ||||
|                 .shortTag("id", (short) entry.getBedrockId()) | ||||
|                 .byteTag("Count", (byte) tag.get("Count").getValue()) | ||||
|                 .shortTag("Damage", (short) entry.getBedrockData()) | ||||
|                 .tag(CompoundTagBuilder.builder().build("tag")); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,80 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.block.entity; | ||||
| 
 | ||||
| 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.TranslatorsInit; | ||||
| import org.geysermc.connector.network.translators.item.ItemEntry; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class ContainerBlockEntityTranslator extends BlockEntityTranslator { | ||||
| 
 | ||||
|     @Override | ||||
|     public List<Tag<?>> translateTag(CompoundTag tag) { | ||||
|         List<Tag<?>> tags = new ArrayList<>(); | ||||
|         ListTag items = tag.get("Items"); | ||||
|         List<com.nukkitx.nbt.tag.CompoundTag> tagsList = new ArrayList<>(); | ||||
|         for (com.github.steveice10.opennbt.tag.builtin.Tag itemTag : items.getValue()) { | ||||
|             tagsList.add(getItem((CompoundTag) itemTag)); | ||||
|         } | ||||
| 
 | ||||
|         com.nukkitx.nbt.tag.ListTag<com.nukkitx.nbt.tag.CompoundTag> bedrockItems = | ||||
|                 new com.nukkitx.nbt.tag.ListTag<>("Items", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); | ||||
|         tags.add(bedrockItems); | ||||
|         return tags; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { | ||||
|         CompoundTag tag = getConstantJavaTag(javaId, x, y, z); | ||||
|         tag.put(new ListTag("Items")); | ||||
|         return tag; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { | ||||
|         CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); | ||||
|         tagBuilder.listTag("Items", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| 
 | ||||
|     protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { | ||||
|         ItemEntry entry = TranslatorsInit.getItemTranslator().getItemEntry((String) tag.get("id").getValue()); | ||||
|         CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() | ||||
|                 .shortTag("id", (short) entry.getBedrockId()) | ||||
|                 .byteTag("Count", (byte) tag.get("Count").getValue()) | ||||
|                 .shortTag("Damage", (short) entry.getBedrockData()) | ||||
|                 .byteTag("Slot", (byte) tag.get("Slot").getValue()) | ||||
|                 .tag(CompoundTagBuilder.builder().build("tag")); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,50 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.block.entity; | ||||
| 
 | ||||
| import com.github.steveice10.opennbt.tag.builtin.CompoundTag; | ||||
| import com.nukkitx.nbt.tag.Tag; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class EmptyBlockEntityTranslator extends BlockEntityTranslator { | ||||
| 
 | ||||
|     @Override | ||||
|     public List<Tag<?>> translateTag(CompoundTag tag) { | ||||
|         return new ArrayList<>(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { | ||||
|         return getConstantJavaTag(javaId, x, y, z); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { | ||||
|         return getConstantBedrockTag(bedrockId, x, y, z); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.block.entity; | ||||
| 
 | ||||
| import com.github.steveice10.mc.protocol.data.message.Message; | ||||
| import com.github.steveice10.opennbt.tag.builtin.CompoundTag; | ||||
| import com.nukkitx.nbt.CompoundTagBuilder; | ||||
| import com.nukkitx.nbt.tag.StringTag; | ||||
| import com.nukkitx.nbt.tag.Tag; | ||||
| 
 | ||||
| import org.geysermc.connector.utils.MessageUtils; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class SignBlockEntityTranslator extends BlockEntityTranslator { | ||||
| 
 | ||||
|     @Override | ||||
|     public List<Tag<?>> translateTag(CompoundTag tag) { | ||||
|         List<Tag<?>> tags = new ArrayList<>(); | ||||
| 
 | ||||
|         String line1 = getOrDefault(tag.getValue().get("Text1"), ""); | ||||
|         String line2 = getOrDefault(tag.getValue().get("Text2"), ""); | ||||
|         String line3 = getOrDefault(tag.getValue().get("Text3"), ""); | ||||
|         String line4 = getOrDefault(tag.getValue().get("Text4"), ""); | ||||
| 
 | ||||
|         tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(Message.fromString(line1)) | ||||
|                 + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line2)) | ||||
|                 + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line3)) | ||||
|                 + "\n" + MessageUtils.getBedrockMessage(Message.fromString(line4)) | ||||
|         )); | ||||
| 
 | ||||
|         return tags; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { | ||||
|         CompoundTag tag = getConstantJavaTag(javaId, x, y, z); | ||||
|         tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text1", "{\"text\":\"\"}")); | ||||
|         tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text2", "{\"text\":\"\"}")); | ||||
|         tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text3", "{\"text\":\"\"}")); | ||||
|         tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text4", "{\"text\":\"\"}")); | ||||
|         return tag; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { | ||||
|         CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); | ||||
|         tagBuilder.stringTag("Text", ""); | ||||
|         return tagBuilder.buildRootTag(); | ||||
|     } | ||||
| } | ||||
|  | @ -43,6 +43,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; | |||
| import com.nukkitx.protocol.bedrock.data.ItemData; | ||||
| 
 | ||||
| import org.geysermc.connector.GeyserConnector; | ||||
| 
 | ||||
| import org.geysermc.connector.utils.MessageUtils; | ||||
| import org.geysermc.connector.utils.Toolbox; | ||||
| 
 | ||||
|  | @ -53,6 +54,8 @@ import java.util.Map; | |||
| 
 | ||||
| public class ItemTranslator { | ||||
| 
 | ||||
|     private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>(); | ||||
| 
 | ||||
|     public ItemStack translateToJava(ItemData data) { | ||||
|         ItemEntry javaItem = getItem(data); | ||||
| 
 | ||||
|  | @ -109,6 +112,11 @@ public class ItemTranslator { | |||
|         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 CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) { | ||||
|         CompoundTag javaTag = new CompoundTag(tag.getName()); | ||||
|         Map<String, Tag> javaValue = javaTag.getValue(); | ||||
|  |  | |||
|  | @ -0,0 +1,55 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.java.world; | ||||
| 
 | ||||
| import com.github.steveice10.mc.protocol.data.game.world.block.value.ChestValue; | ||||
| import com.github.steveice10.mc.protocol.data.game.world.block.value.EndGatewayValue; | ||||
| import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerBlockValuePacket; | ||||
| import com.nukkitx.math.vector.Vector3i; | ||||
| import com.nukkitx.protocol.bedrock.packet.BlockEventPacket; | ||||
| 
 | ||||
| import org.geysermc.connector.network.session.GeyserSession; | ||||
| import org.geysermc.connector.network.translators.PacketTranslator; | ||||
| 
 | ||||
| public class JavaBlockValueTranslator extends PacketTranslator<ServerBlockValuePacket> { | ||||
| 
 | ||||
|     @Override | ||||
|     public void translate(ServerBlockValuePacket packet, GeyserSession session) { | ||||
|         BlockEventPacket blockEventPacket = new BlockEventPacket(); | ||||
|         blockEventPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), | ||||
|                 packet.getPosition().getY(), packet.getPosition().getZ())); | ||||
|         if (packet.getValue() instanceof ChestValue) { | ||||
|             ChestValue value = (ChestValue) packet.getValue() ; | ||||
|             blockEventPacket.setEventType(1); | ||||
|             blockEventPacket.setEventData(value.getViewers() > 0 ? 1 : 0); | ||||
|             session.getUpstream().sendPacket(blockEventPacket); | ||||
|         } | ||||
|         if (packet.getValue() instanceof EndGatewayValue) { | ||||
|             blockEventPacket.setEventType(1); | ||||
|             session.getUpstream().sendPacket(blockEventPacket); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -27,15 +27,23 @@ package org.geysermc.connector.network.translators.java.world; | |||
| 
 | ||||
| import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; | ||||
| import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; | ||||
| import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; | ||||
| import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket; | ||||
| import com.nukkitx.math.vector.Vector3i; | ||||
| import com.nukkitx.nbt.NbtUtils; | ||||
| import com.nukkitx.nbt.stream.NBTOutputStream; | ||||
| import com.nukkitx.nbt.tag.CompoundTag; | ||||
| import com.nukkitx.network.VarInts; | ||||
| import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; | ||||
| 
 | ||||
| import io.netty.buffer.ByteBuf; | ||||
| import io.netty.buffer.ByteBufOutputStream; | ||||
| import io.netty.buffer.Unpooled; | ||||
| 
 | ||||
| import org.geysermc.connector.GeyserConnector; | ||||
| 
 | ||||
| import it.unimi.dsi.fastutil.ints.Int2ObjectMap; | ||||
| 
 | ||||
| import org.geysermc.connector.network.session.GeyserSession; | ||||
| import org.geysermc.connector.network.translators.BiomeTranslator; | ||||
| import org.geysermc.connector.network.translators.PacketTranslator; | ||||
|  | @ -46,7 +54,6 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac | |||
| 
 | ||||
|     @Override | ||||
|     public void translate(ServerChunkDataPacket packet, GeyserSession session) { | ||||
|         // Not sure if this is safe or not, however without this the client usually times out | ||||
|         GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> { | ||||
|             try { | ||||
|                 if (packet.getColumn().getBiomeData() != null) { //Full chunk | ||||
|  | @ -71,6 +78,14 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac | |||
|                     byteBuf.writeByte(0); // Border blocks - Edu edition only | ||||
|                     VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now | ||||
| 
 | ||||
|                     ByteBufOutputStream stream = new ByteBufOutputStream(Unpooled.buffer()); | ||||
|                     NBTOutputStream nbtStream = NbtUtils.createNetworkWriter(stream); | ||||
|                     for (CompoundTag blockEntity : chunkData.blockEntities) { | ||||
|                         nbtStream.write(blockEntity); | ||||
|                     } | ||||
| 
 | ||||
|                     byteBuf.writeBytes(stream.buffer()); | ||||
| 
 | ||||
|                     byte[] payload = new byte[byteBuf.writerIndex()]; | ||||
|                     byteBuf.readBytes(payload); | ||||
| 
 | ||||
|  | @ -81,6 +96,16 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac | |||
|                     levelChunkPacket.setChunkZ(packet.getColumn().getZ()); | ||||
|                     levelChunkPacket.setData(payload); | ||||
|                     session.getUpstream().sendPacket(levelChunkPacket); | ||||
| 
 | ||||
|                     // Signs have to be sent after the chunk since in later versions they aren't included in the block entities | ||||
|                     for (Int2ObjectMap.Entry<CompoundTag> blockEntityEntry : chunkData.signs.int2ObjectEntrySet()) { | ||||
|                         int x = blockEntityEntry.getValue().getInt("x"); | ||||
|                         int y = blockEntityEntry.getValue().getInt("y"); | ||||
|                         int z = blockEntityEntry.getValue().getInt("z"); | ||||
| 
 | ||||
|                         ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z)); | ||||
|                     } | ||||
|                     chunkData.signs.clear(); | ||||
|                 } else { | ||||
|                     final int xOffset = packet.getColumn().getX() << 4; | ||||
|                     final int zOffset = packet.getColumn().getZ() << 4; | ||||
|  |  | |||
|  | @ -0,0 +1,54 @@ | |||
| /* | ||||
|  * Copyright (c) 2019 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.java.world; | ||||
| 
 | ||||
| import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket; | ||||
| 
 | ||||
| import org.geysermc.connector.network.session.GeyserSession; | ||||
| import org.geysermc.connector.network.translators.PacketTranslator; | ||||
| import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; | ||||
| import org.geysermc.connector.utils.BlockEntityUtils; | ||||
| 
 | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| public class JavaUpdateTileEntityTranslator extends PacketTranslator<ServerUpdateTileEntityPacket> { | ||||
| 
 | ||||
|     @Override | ||||
|     public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) { | ||||
|         String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name()); | ||||
|         BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id); | ||||
|         if (id.equalsIgnoreCase("Sign")) { | ||||
|             // Delay so chunks can finish sending | ||||
|             session.getConnector().getGeneralThreadPool().schedule(() -> | ||||
|                     BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getNbt()), packet.getPosition()), | ||||
|                     5, | ||||
|                     TimeUnit.SECONDS | ||||
|             ); | ||||
|         } else { | ||||
|             BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getNbt()), packet.getPosition()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,47 @@ | |||
| package org.geysermc.connector.utils; | ||||
| 
 | ||||
| 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.TranslatorsInit; | ||||
| import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; | ||||
| 
 | ||||
| public class BlockEntityUtils { | ||||
| 
 | ||||
|     private static final BlockEntityTranslator EMPTY_TRANSLATOR = TranslatorsInit.getBlockEntityTranslators().get("Empty"); | ||||
| 
 | ||||
|     public static String getBedrockBlockEntityId(String id) { | ||||
|         // This is the only exception when it comes to block entity ids | ||||
|         if (id.contains("piston_head")) | ||||
|             return "PistonArm"; | ||||
| 
 | ||||
|         id = id.toLowerCase() | ||||
|             .replace("minecraft:", "") | ||||
|             .replace("_", " "); | ||||
|         String[] words = id.split(" "); | ||||
|         for (int i = 0; i < words.length; i++) { | ||||
|             words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase(); | ||||
|         } | ||||
| 
 | ||||
|         id = String.join(" ", words); | ||||
|         return id.replace(" ", ""); | ||||
|     } | ||||
| 
 | ||||
|     public static BlockEntityTranslator getBlockEntityTranslator(String name) { | ||||
|         BlockEntityTranslator blockEntityTranslator = TranslatorsInit.getBlockEntityTranslators().get(name); | ||||
|         if (blockEntityTranslator == null) { | ||||
|             return EMPTY_TRANSLATOR; | ||||
|         } | ||||
| 
 | ||||
|         return blockEntityTranslator; | ||||
|     } | ||||
| 
 | ||||
|     public static void updateBlockEntity(GeyserSession session, com.nukkitx.nbt.tag.CompoundTag blockEntity, Position position) { | ||||
|         BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); | ||||
|         blockEntityPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ())); | ||||
|         blockEntityPacket.setData(blockEntity); | ||||
|         session.getUpstream().sendPacket(blockEntityPacket); | ||||
|     } | ||||
| } | ||||
|  | @ -29,25 +29,33 @@ import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; | |||
| import com.github.steveice10.mc.protocol.data.game.chunk.Column; | ||||
| import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; | ||||
| import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; | ||||
| import com.github.steveice10.opennbt.tag.builtin.CompoundTag; | ||||
| import com.nukkitx.math.vector.Vector3i; | ||||
| import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket; | ||||
| import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; | ||||
| 
 | ||||
| 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.TranslatorsInit; | ||||
| import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; | ||||
| import org.geysermc.connector.world.chunk.ChunkPosition; | ||||
| import org.geysermc.connector.network.translators.block.BlockTranslator; | ||||
| import org.geysermc.connector.world.chunk.ChunkSection; | ||||
| 
 | ||||
| import static org.geysermc.connector.network.translators.block.BlockTranslator.BEDROCK_WATER_ID; | ||||
| 
 | ||||
| public class ChunkUtils { | ||||
| 
 | ||||
|     public static ChunkData translateToBedrock(Column column) { | ||||
|         ChunkData chunkData = new ChunkData(); | ||||
| 
 | ||||
|         Chunk[] chunks = column.getChunks(); | ||||
|         int chunkSectionCount = chunks.length; | ||||
|         chunkData.sections = new ChunkSection[chunkSectionCount]; | ||||
|         chunkData.sections = new ChunkSection[chunks.length]; | ||||
| 
 | ||||
|         for (int chunkY = 0; chunkY < chunkSectionCount; chunkY++) { | ||||
|         CompoundTag[] blockEntities = column.getTileEntities(); | ||||
|         for (int chunkY = 0; chunkY < chunks.length; chunkY++) { | ||||
|             chunkData.sections[chunkY] = new ChunkSection(); | ||||
|             Chunk chunk = chunks[chunkY]; | ||||
| 
 | ||||
|  | @ -55,14 +63,18 @@ public class ChunkUtils { | |||
|                 continue; | ||||
| 
 | ||||
|             ChunkSection section = chunkData.sections[chunkY]; | ||||
| 
 | ||||
|             for (int x = 0; x < 16; x++) { | ||||
|                 for (int y = 0; y < 16; y++) { | ||||
|                     for (int z = 0; z < 16; z++) { | ||||
|                         BlockState blockState = chunk.get(x, y, z); | ||||
|                         int id = BlockTranslator.getBedrockBlockId(blockState); | ||||
| 
 | ||||
|                         section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), id); | ||||
|                         if (BlockTranslator.getBlockEntityString(blockState) != null && BlockTranslator.getBlockEntityString(blockState).contains("sign[")) { | ||||
|                             Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); | ||||
|                             chunkData.signs.put(blockState.getId(), TranslatorsInit.getBlockEntityTranslators().get("Sign").getDefaultBedrockTag("Sign", pos.getX(), pos.getY(), pos.getZ())); | ||||
|                         } else { | ||||
|                             section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), id); | ||||
|                         } | ||||
| 
 | ||||
|                         if (BlockTranslator.isWaterlogged(blockState)) { | ||||
|                             section.getBlockStorageArray()[1].setFullBlock(ChunkSection.blockPosition(x, y, z), BEDROCK_WATER_ID); | ||||
|  | @ -71,6 +83,24 @@ public class ChunkUtils { | |||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         com.nukkitx.nbt.tag.CompoundTag[] bedrockBlockEntities = new com.nukkitx.nbt.tag.CompoundTag[blockEntities.length]; | ||||
|         for (int i = 0; i < blockEntities.length; i++) { | ||||
|             CompoundTag tag = blockEntities[i]; | ||||
|             String tagName; | ||||
|             if (!tag.contains("id")) { | ||||
|                 GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue()); | ||||
|                 tagName = "Empty"; | ||||
|             } else { | ||||
|                 tagName = (String) tag.get("id").getValue(); | ||||
|             } | ||||
| 
 | ||||
|             String id = BlockEntityUtils.getBedrockBlockEntityId(tagName); | ||||
|             BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id); | ||||
|             bedrockBlockEntities[i] = blockEntityTranslator.getBlockEntityTag(tag); | ||||
|         } | ||||
| 
 | ||||
|         chunkData.blockEntities = bedrockBlockEntities; | ||||
|         return chunkData; | ||||
|     } | ||||
| 
 | ||||
|  | @ -128,6 +158,7 @@ public class ChunkUtils { | |||
|     public static final class ChunkData { | ||||
|         public ChunkSection[] sections; | ||||
| 
 | ||||
|         public byte[] blockEntities = new byte[0]; | ||||
|         public com.nukkitx.nbt.tag.CompoundTag[] blockEntities = new com.nukkitx.nbt.tag.CompoundTag[0]; | ||||
|         public Int2ObjectMap<com.nukkitx.nbt.tag.CompoundTag> signs = new Int2ObjectOpenHashMap<>(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -157,7 +157,7 @@ public class MessageUtils { | |||
|                 base += "r"; | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|                 return ""; | ||||
|         } | ||||
| 
 | ||||
|         return base; | ||||
|  |  | |||
|  | @ -184,7 +184,6 @@ public class SkinUtils { | |||
| 
 | ||||
|                         if (skinAndCapeConsumer != null) skinAndCapeConsumer.accept(skinAndCape); | ||||
|                     }); | ||||
| 
 | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,8 +31,6 @@ import lombok.EqualsAndHashCode; | |||
| import lombok.Getter; | ||||
| import lombok.Setter; | ||||
| 
 | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| @Getter | ||||
| @Setter | ||||
| @AllArgsConstructor | ||||
|  | @ -50,7 +48,6 @@ public class ChunkPosition { | |||
|         int chunkX = x & 15; | ||||
|         int chunkY = y & 15; | ||||
|         int chunkZ = z & 15; | ||||
| 
 | ||||
|         return new Position(chunkX, chunkY, chunkZ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue