21w20a support

This commit is contained in:
Camotoy 2021-05-19 22:24:11 -04:00
parent 024655f008
commit b5307ab3ed
No known key found for this signature in database
GPG Key ID: 7EEFB66FE798081F
87 changed files with 314 additions and 577 deletions

View File

@ -18,7 +18,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.220 and Minecraft Java v1.16.4 - v1.16.5. ### Currently supporting Minecraft Bedrock v1.16.220.52 and Minecraft Java 21w20a.
## Setting Up ## Setting Up
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.
@ -39,6 +39,8 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set
- Some Entity Flags - Some Entity Flags
- Structure block UI - Structure block UI
Extended height features can be "supported", but require additional work.
## What can't be fixed ## What can't be fixed
The following things cannot be fixed without changes to Bedrock. As of now, they are not fixable in Geyser. The following things cannot be fixed without changes to Bedrock. As of now, they are not fixable in Geyser.

View File

@ -150,11 +150,6 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
if (isLegacy) if (isLegacy)
geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected; falling back to ViaVersion for block state retrieval."); geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected; falling back to ViaVersion for block state retrieval.");
boolean use3dBiomes = isCompatible(Bukkit.getServer().getVersion(), "1.16.0");
if (!use3dBiomes) {
geyserLogger.debug("Legacy version of Minecraft (1.15.2 or older) detected; not using 3D biomes.");
}
boolean isPre1_12 = !isCompatible(Bukkit.getServer().getVersion(), "1.12.0"); boolean isPre1_12 = !isCompatible(Bukkit.getServer().getVersion(), "1.12.0");
// Set if we need to use a different method for getting a player's locale // Set if we need to use a different method for getting a player's locale
SpigotCommandSender.setUseLegacyLocaleMethod(isPre1_12); SpigotCommandSender.setUseLegacyLocaleMethod(isPre1_12);
@ -170,11 +165,11 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
this.geyserWorldManager = new GeyserSpigot1_12NativeWorldManager(this); this.geyserWorldManager = new GeyserSpigot1_12NativeWorldManager(this);
} else { } else {
// Post-1.13 // Post-1.13
this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this, use3dBiomes); this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this);
} }
} else { } else {
// No ViaVersion // No ViaVersion
this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, use3dBiomes); this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this);
} }
geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion); geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion);
} catch (Exception e) { } catch (Exception e) {
@ -196,7 +191,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
this.geyserWorldManager = new GeyserSpigotFallbackWorldManager(this); this.geyserWorldManager = new GeyserSpigotFallbackWorldManager(this);
} else { } else {
// Post-1.13 // Post-1.13
this.geyserWorldManager = new GeyserSpigotWorldManager(this, use3dBiomes); this.geyserWorldManager = new GeyserSpigotWorldManager(this);
} }
geyserLogger.debug("Using default world manager: " + this.geyserWorldManager.getClass()); geyserLogger.debug("Using default world manager: " + this.geyserWorldManager.getClass());
} }

View File

@ -25,9 +25,7 @@
package org.geysermc.platform.spigot.world.manager; package org.geysermc.platform.spigot.world.manager;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -63,7 +61,7 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
private final List<Pair<Integer, Protocol>> protocolList; private final List<Pair<Integer, Protocol>> protocolList;
public GeyserSpigot1_12WorldManager(Plugin plugin) { public GeyserSpigot1_12WorldManager(Plugin plugin) {
super(plugin, false); super(plugin);
this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData(); this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
this.protocolList = ProtocolRegistry.getProtocolPath(CLIENT_PROTOCOL_VERSION, this.protocolList = ProtocolRegistry.getProtocolPath(CLIENT_PROTOCOL_VERSION,
ProtocolVersion.v1_13.getVersion()); ProtocolVersion.v1_13.getVersion());
@ -117,28 +115,6 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
return blockId; return blockId;
} }
@SuppressWarnings("deprecation")
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
if (player == null) {
return;
}
World world = player.getWorld();
// Get block entity storage
BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class);
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
Block block = world.getBlockAt((x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ);
// Black magic that gets the old block state ID
int blockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
chunk.set(blockX, blockY, blockZ, getLegacyBlock(storage, blockId, (x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ));
}
}
}
}
@Override @Override
public boolean isLegacy() { public boolean isLegacy() {
return true; return true;

View File

@ -25,7 +25,6 @@
package org.geysermc.platform.spigot.world.manager; package org.geysermc.platform.spigot.world.manager;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
@ -37,8 +36,7 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator;
*/ */
public class GeyserSpigotFallbackWorldManager extends GeyserSpigotWorldManager { public class GeyserSpigotFallbackWorldManager extends GeyserSpigotWorldManager {
public GeyserSpigotFallbackWorldManager(Plugin plugin) { public GeyserSpigotFallbackWorldManager(Plugin plugin) {
// Since this is pre-1.13 (and thus pre-1.15), there will never be 3D biomes. super(plugin);
super(plugin, false);
} }
@Override @Override
@ -46,11 +44,6 @@ public class GeyserSpigotFallbackWorldManager extends GeyserSpigotWorldManager {
return BlockTranslator.JAVA_AIR_ID; return BlockTranslator.JAVA_AIR_ID;
} }
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
// Do nothing, since we can't do anything with the chunk
}
@Override @Override
public boolean hasOwnChunkCache() { public boolean hasOwnChunkCache() {
return false; return false;

View File

@ -46,8 +46,8 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl
private final Int2IntMap oldToNewBlockId; private final Int2IntMap oldToNewBlockId;
public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin, boolean use3dBiomes) { public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin) {
super(plugin, use3dBiomes); super(plugin);
IntList allBlockStates = adapter.getAllBlockStates(); IntList allBlockStates = adapter.getAllBlockStates();
oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size()); oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size());
ProtocolVersion serverVersion = plugin.getServerProtocolVersion(); ProtocolVersion serverVersion = plugin.getServerProtocolVersion();

View File

@ -36,8 +36,8 @@ import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager { public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
protected final SpigotWorldAdapter adapter; protected final SpigotWorldAdapter adapter;
public GeyserSpigotNativeWorldManager(Plugin plugin, boolean use3dBiomes) { public GeyserSpigotNativeWorldManager(Plugin plugin) {
super(plugin, use3dBiomes); super(plugin);
adapter = SpigotAdapters.getWorldAdapter(); adapter = SpigotAdapters.getWorldAdapter();
} }

View File

@ -25,18 +25,13 @@
package org.geysermc.platform.spigot.world.manager; package org.geysermc.platform.spigot.world.manager;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.MinecraftConstants; import com.github.steveice10.mc.protocol.MinecraftConstants;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtType;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Lectern; import org.bukkit.block.Lectern;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
@ -44,17 +39,13 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.inventory.translators.LecternInventoryTranslator; import org.geysermc.connector.network.translators.inventory.translators.LecternInventoryTranslator;
import org.geysermc.connector.network.translators.world.GeyserWorldManager; import org.geysermc.connector.network.translators.world.GeyserWorldManager;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.BlockEntityUtils; import org.geysermc.connector.utils.BlockEntityUtils;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.GameRule; import org.geysermc.connector.utils.GameRule;
import org.geysermc.connector.utils.LanguageUtils;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -67,48 +58,10 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
*/ */
protected static final int CLIENT_PROTOCOL_VERSION = MinecraftConstants.PROTOCOL_VERSION; protected static final int CLIENT_PROTOCOL_VERSION = MinecraftConstants.PROTOCOL_VERSION;
/**
* Whether the server is pre-1.16 and therefore does not support 3D biomes on an API level guaranteed.
*/
private final boolean use3dBiomes;
/**
* Stores a list of {@link Biome} ordinal numbers to Minecraft biome numeric IDs.
*
* Working with the Biome enum in Spigot poses two problems:
* 1: The Biome enum values change in both order and names over the years.
* 2: There is no way to get the Minecraft biome ID from the name itself with Spigot.
* To solve both of these problems, we store a JSON file of every Biome enum that has existed,
* along with its 1.16 biome number.
*
* The key is the Spigot Biome ordinal; the value is the Minecraft Java biome numerical ID
*/
private final Int2IntMap biomeToIdMap = new Int2IntOpenHashMap(Biome.values().length);
private final Plugin plugin; private final Plugin plugin;
public GeyserSpigotWorldManager(Plugin plugin, boolean use3dBiomes) { public GeyserSpigotWorldManager(Plugin plugin) {
this.use3dBiomes = use3dBiomes;
this.plugin = plugin; this.plugin = plugin;
// Load the values into the biome-to-ID map
InputStream biomeStream = FileUtils.getResource("biomes.json");
JsonNode biomes;
try {
biomes = GeyserConnector.JSON_MAPPER.readTree(biomeStream);
} catch (Exception e) {
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e);
}
// Only load in the biomes that are present in this version of Minecraft
for (Biome enumBiome : Biome.values()) {
JsonNode biome = biomes.get(enumBiome.toString());
if (biome != null) {
biomeToIdMap.put(enumBiome.ordinal(), biome.intValue());
} else {
GeyserConnector.getInstance().getLogger().debug("No biome mapping found for " + enumBiome.toString() +
", defaulting to 0");
biomeToIdMap.put(enumBiome.ordinal(), 0);
}
}
} }
@Override @Override
@ -121,64 +74,11 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
return BlockTranslator.getJavaIdBlockMap().getOrDefault(world.getBlockAt(x, y, z).getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID); return BlockTranslator.getJavaIdBlockMap().getOrDefault(world.getBlockAt(x, y, z).getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID);
} }
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
Player bukkitPlayer;
if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
return;
}
World world = bukkitPlayer.getWorld();
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
Block block = world.getBlockAt((x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ);
int id = BlockTranslator.getJavaIdBlockMap().getOrDefault(block.getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID);
chunk.set(blockX, blockY, blockZ, id);
}
}
}
}
@Override @Override
public boolean hasOwnChunkCache() { public boolean hasOwnChunkCache() {
return true; return true;
} }
@Override
@SuppressWarnings("deprecation")
public int[] getBiomeDataAt(GeyserSession session, int x, int z) {
int[] biomeData = new int[1024];
World world = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld();
int chunkX = x << 4;
int chunkZ = z << 4;
int chunkXmax = chunkX + 16;
int chunkZmax = chunkZ + 16;
// 3D biomes didn't exist until 1.15
if (use3dBiomes) {
for (int localX = chunkX; localX < chunkXmax; localX += 4) {
for (int localY = 0; localY < 255; localY += + 4) {
for (int localZ = chunkZ; localZ < chunkZmax; localZ += 4) {
// Index is based on wiki.vg's index requirements
final int i = ((localY >> 2) & 63) << 4 | ((localZ >> 2) & 3) << 2 | ((localX >> 2) & 3);
biomeData[i] = biomeToIdMap.getOrDefault(world.getBiome(localX, localY, localZ).ordinal(), 0);
}
}
}
} else {
// Looks like the same code, but we're not checking the Y coordinate here
for (int localX = chunkX; localX < chunkXmax; localX += 4) {
for (int localY = 0; localY < 255; localY += + 4) {
for (int localZ = chunkZ; localZ < chunkZmax; localZ += 4) {
// Index is based on wiki.vg's index requirements
final int i = ((localY >> 2) & 63) << 4 | ((localZ >> 2) & 3) << 2 | ((localX >> 2) & 3);
biomeData[i] = biomeToIdMap.getOrDefault(world.getBiome(localX, localZ).ordinal(), 0);
}
}
}
}
return biomeData;
}
@Override @Override
public NbtMap getLecternDataAt(GeyserSession session, int x, int y, int z, boolean isChunkLoad) { public NbtMap getLecternDataAt(GeyserSession session, int x, int y, int z, boolean isChunkLoad) {
// Run as a task to prevent async issues // Run as a task to prevent async issues

View File

@ -1,155 +0,0 @@
{
"MUTATED_ICE_FLATS" : 140,
"MUTATED_TAIGA" : 133,
"SAVANNA_PLATEAU_MOUNTAINS" : 164,
"DEEP_WARM_OCEAN" : 47,
"REDWOOD_TAIGA_HILLS" : 33,
"THE_VOID" : 127,
"COLD_TAIGA_MOUNTAINS" : 158,
"BAMBOO_JUNGLE_HILLS" : 169,
"MOUNTAINS" : 3,
"MESA_PLATEAU" : 39,
"SNOWY_TAIGA_HILLS" : 31,
"DEEP_FROZEN_OCEAN" : 50,
"EXTREME_HILLS" : 3,
"BIRCH_FOREST_MOUNTAINS" : 155,
"FOREST" : 4,
"BIRCH_FOREST" : 27,
"SNOWY_TUNDRA" : 12,
"ICE_SPIKES" : 140,
"FROZEN_OCEAN" : 10,
"WARPED_FOREST" : 172,
"WOODED_BADLANDS_PLATEAU" : 38,
"BADLANDS_PLATEAU" : 39,
"ICE_PLAINS_SPIKES" : 140,
"MEGA_TAIGA" : 32,
"MUTATED_SAVANNA_ROCK" : 164,
"SAVANNA_PLATEAU" : 36,
"DARK_FOREST_HILLS" : 157,
"END_MIDLANDS" : 41,
"SHATTERED_SAVANNA_PLATEAU" : 164,
"SAVANNA" : 35,
"MUSHROOM_ISLAND_SHORE" : 15,
"SWAMP" : 6,
"ICE_MOUNTAINS" : 13,
"BEACH" : 16,
"MUTATED_MESA_CLEAR_ROCK" : 167,
"END_HIGHLANDS" : 42,
"COLD_BEACH" : 26,
"JUNGLE" : 21,
"MUTATED_TAIGA_COLD" : 158,
"TALL_BIRCH_HILLS" : 156,
"DARK_FOREST" : 29,
"WOODED_HILLS" : 18,
"HELL" : 8,
"MUTATED_REDWOOD_TAIGA" : 160,
"MESA_PLATEAU_FOREST" : 38,
"MUSHROOM_ISLAND" : 14,
"BADLANDS" : 37,
"END_BARRENS" : 43,
"MUTATED_EXTREME_HILLS_WITH_TREES" : 162,
"MUTATED_JUNGLE_EDGE" : 151,
"MODIFIED_BADLANDS_PLATEAU" : 167,
"ROOFED_FOREST_MOUNTAINS" : 157,
"SOUL_SAND_VALLEY" : 170,
"DESERT" : 2,
"MUTATED_PLAINS" : 129,
"MUTATED_BIRCH_FOREST" : 155,
"WOODED_MOUNTAINS" : 34,
"TAIGA_HILLS" : 19,
"BAMBOO_JUNGLE" : 168,
"SWAMPLAND_MOUNTAINS" : 134,
"DESERT_MOUNTAINS" : 130,
"REDWOOD_TAIGA" : 32,
"MUSHROOM_FIELDS" : 14,
"GIANT_TREE_TAIGA_HILLS" : 33,
"PLAINS" : 1,
"JUNGLE_EDGE" : 23,
"SAVANNA_MOUNTAINS" : 163,
"DEEP_COLD_OCEAN" : 49,
"DESERT_LAKES" : 130,
"MOUNTAIN_EDGE" : 20,
"SNOWY_MOUNTAINS" : 13,
"MESA_PLATEAU_MOUNTAINS" : 167,
"JUNGLE_MOUNTAINS" : 149,
"SMALLER_EXTREME_HILLS" : 20,
"MESA_PLATEAU_FOREST_MOUNTAINS" : 166,
"NETHER_WASTES" : 8,
"BIRCH_FOREST_HILLS_MOUNTAINS" : 156,
"MUTATED_JUNGLE" : 149,
"WARM_OCEAN" : 44,
"DEEP_OCEAN" : 24,
"STONE_BEACH" : 25,
"MODIFIED_JUNGLE" : 149,
"MUTATED_SAVANNA" : 163,
"TAIGA_COLD_HILLS" : 31,
"OCEAN" : 0,
"SMALL_END_ISLANDS" : 40,
"MUSHROOM_FIELD_SHORE" : 15,
"GRAVELLY_MOUNTAINS" : 131,
"FROZEN_RIVER" : 11,
"TAIGA_COLD" : 30,
"BASALT_DELTAS" : 173,
"EXTREME_HILLS_WITH_TREES" : 34,
"MEGA_TAIGA_HILLS" : 33,
"MUTATED_FOREST" : 132,
"MUTATED_BIRCH_FOREST_HILLS" : 156,
"SKY" : 9,
"LUKEWARM_OCEAN" : 45,
"EXTREME_HILLS_MOUNTAINS" : 131,
"COLD_TAIGA_HILLS" : 31,
"THE_END" : 9,
"SUNFLOWER_PLAINS" : 129,
"SAVANNA_ROCK" : 36,
"ERODED_BADLANDS" : 165,
"STONE_SHORE" : 25,
"EXTREME_HILLS_PLUS_MOUNTAINS" : 162,
"CRIMSON_FOREST" : 171,
"VOID" : 127,
"SNOWY_TAIGA" : 30,
"SNOWY_TAIGA_MOUNTAINS" : 158,
"FLOWER_FOREST" : 132,
"COLD_OCEAN" : 46,
"BEACHES" : 16,
"MESA" : 37,
"MUSHROOM_SHORE" : 15,
"MESA_CLEAR_ROCK" : 39,
"NETHER" : 8,
"ICE_PLAINS" : 12,
"SHATTERED_SAVANNA" : 163,
"ROOFED_FOREST" : 29,
"GIANT_SPRUCE_TAIGA_HILLS" : 161,
"SNOWY_BEACH" : 26,
"MESA_BRYCE" : 165,
"JUNGLE_EDGE_MOUNTAINS" : 151,
"MUTATED_DESERT" : 130,
"MODIFIED_GRAVELLY_MOUNTAINS" : 158,
"MEGA_SPRUCE_TAIGA" : 160,
"TAIGA_MOUNTAINS" : 133,
"SMALL_MOUNTAINS" : 20,
"EXTREME_HILLS_PLUS" : 34,
"GIANT_SPRUCE_TAIGA" : 160,
"FOREST_HILLS" : 18,
"DESERT_HILLS" : 17,
"MUTATED_REDWOOD_TAIGA_HILLS" : 161,
"MEGA_SPRUCE_TAIGA_HILLS" : 161,
"RIVER" : 7,
"GIANT_TREE_TAIGA" : 32,
"SWAMPLAND" : 6,
"JUNGLE_HILLS" : 22,
"TALL_BIRCH_FOREST" : 155,
"DEEP_LUKEWARM_OCEAN" : 48,
"MESA_ROCK" : 38,
"SWAMP_HILLS" : 134,
"MODIFIED_WOODED_BADLANDS_PLATEAU" : 166,
"MODIFIED_JUNGLE_EDGE" : 151,
"BIRCH_FOREST_HILLS" : 28,
"COLD_TAIGA" : 30,
"TAIGA" : 5,
"MUTATED_MESA_ROCK" : 166,
"MUTATED_SWAMPLAND" : 134,
"ICE_FLATS" : 12,
"MUTATED_ROOFED_FOREST" : 157,
"MUTATED_MESA" : 165,
"MUTATED_EXTREME_HILLS" : 131
}

View File

@ -122,7 +122,7 @@
<dependency> <dependency>
<groupId>com.github.steveice10</groupId> <groupId>com.github.steveice10</groupId>
<artifactId>mcprotocollib</artifactId> <artifactId>mcprotocollib</artifactId>
<version>21w17a-SNAPSHOT</version> <version>21w20a-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>

View File

@ -44,7 +44,7 @@ public class AbstractArrowEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
byte data = (byte) entityMetadata.getValue(); byte data = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.CRITICAL, (data & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.CRITICAL, (data & 0x01) == 0x01);

View File

@ -52,12 +52,12 @@ public class AreaEffectCloudEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, entityMetadata.getValue()); metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, entityMetadata.getValue());
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue()); metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue());
} else if (entityMetadata.getId() == 8) { } else if (entityMetadata.getId() == 9) {
metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue()); metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue());
} else if (entityMetadata.getId() == 10) { } else if (entityMetadata.getId() == 11) {
Particle particle = (Particle) entityMetadata.getValue(); Particle particle = (Particle) entityMetadata.getValue();
int particleId = EffectRegistry.getParticleId(particle.getType()); int particleId = EffectRegistry.getParticleId(particle.getType());
if (particleId != -1) { if (particleId != -1) {

View File

@ -87,24 +87,24 @@ public class BoatEntity extends Entity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Time since last hit // Time since last hit
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
metadata.put(EntityData.HURT_TIME, entityMetadata.getValue()); metadata.put(EntityData.HURT_TIME, entityMetadata.getValue());
} }
// Rocking direction // Rocking direction
if (entityMetadata.getId() == 8) { if (entityMetadata.getId() == 9) {
metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue()); metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue());
} }
// 'Health' in Bedrock, damage taken in Java // 'Health' in Bedrock, damage taken in Java
if (entityMetadata.getId() == 9) { if (entityMetadata.getId() == 10) {
// Not exactly health but it makes motion in Bedrock // Not exactly health but it makes motion in Bedrock
metadata.put(EntityData.HEALTH, 40 - ((int) (float) entityMetadata.getValue())); metadata.put(EntityData.HEALTH, 40 - ((int) (float) entityMetadata.getValue()));
} }
if (entityMetadata.getId() == 10) { if (entityMetadata.getId() == 11) {
metadata.put(EntityData.VARIANT, entityMetadata.getValue()); metadata.put(EntityData.VARIANT, entityMetadata.getValue());
} else if (entityMetadata.getId() == 11) { } else if (entityMetadata.getId() == 12) {
isPaddlingLeft = (boolean) entityMetadata.getValue(); isPaddlingLeft = (boolean) entityMetadata.getValue();
if (isPaddlingLeft) { if (isPaddlingLeft) {
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
@ -124,7 +124,7 @@ public class BoatEntity extends Entity {
metadata.put(EntityData.ROW_TIME_LEFT, 0.0f); metadata.put(EntityData.ROW_TIME_LEFT, 0.0f);
} }
} }
else if (entityMetadata.getId() == 12) { else if (entityMetadata.getId() == 13) {
isPaddlingRight = (boolean) entityMetadata.getValue(); isPaddlingRight = (boolean) entityMetadata.getValue();
if (isPaddlingRight) { if (isPaddlingRight) {
paddleTimeRight = 0f; paddleTimeRight = 0f;
@ -139,7 +139,7 @@ public class BoatEntity extends Entity {
} else { } else {
metadata.put(EntityData.ROW_TIME_RIGHT, 0.0f); metadata.put(EntityData.ROW_TIME_RIGHT, 0.0f);
} }
} else if (entityMetadata.getId() == 13) { } else if (entityMetadata.getId() == 14) {
// Possibly - I don't think this does anything? // Possibly - I don't think this does anything?
metadata.put(EntityData.BOAT_BUBBLE_TIME, entityMetadata.getValue()); metadata.put(EntityData.BOAT_BUBBLE_TIME, entityMetadata.getValue());
} }

View File

@ -46,10 +46,10 @@ public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 13) { if (entityMetadata.getId() == 14) {
metadata.put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue()); metadata.put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue());
} }
if (entityMetadata.getId() == 14) { if (entityMetadata.getId() == 15) {
metadata.put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage((Component) entityMetadata.getValue())); metadata.put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage((Component) entityMetadata.getValue()));
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -56,7 +56,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Custom block // Custom block
if (entityMetadata.getId() == 10) { if (entityMetadata.getId() == 11) {
customBlock = (int) entityMetadata.getValue(); customBlock = (int) entityMetadata.getValue();
if (showCustomBlock) { if (showCustomBlock) {
@ -65,7 +65,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
} }
// Custom block offset // Custom block offset
if (entityMetadata.getId() == 11) { if (entityMetadata.getId() == 12) {
customBlockOffset = (int) entityMetadata.getValue(); customBlockOffset = (int) entityMetadata.getValue();
if (showCustomBlock) { if (showCustomBlock) {
@ -74,7 +74,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
} }
// If the custom block should be enabled // If the custom block should be enabled
if (entityMetadata.getId() == 12) { if (entityMetadata.getId() == 13) {
if ((boolean) entityMetadata.getValue()) { if ((boolean) entityMetadata.getValue()) {
showCustomBlock = true; showCustomBlock = true;
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(customBlock)); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(customBlock));

View File

@ -47,7 +47,7 @@ public class EnderCrystalEntity extends Entity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Show beam // Show beam
// Usually performed client-side on Bedrock except for Ender Dragon respawn event // Usually performed client-side on Bedrock except for Ender Dragon respawn event
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
if (entityMetadata.getValue() instanceof Position) { if (entityMetadata.getValue() instanceof Position) {
Position pos = (Position) entityMetadata.getValue(); Position pos = (Position) entityMetadata.getValue();
metadata.put(EntityData.BLOCK_TARGET, Vector3i.from(pos.getX(), pos.getY(), pos.getZ())); metadata.put(EntityData.BLOCK_TARGET, Vector3i.from(pos.getX(), pos.getY(), pos.getZ()));
@ -56,7 +56,7 @@ public class EnderCrystalEntity extends Entity {
} }
} }
// There is a base located on the ender crystal // There is a base located on the ender crystal
if (entityMetadata.getId() == 8) { if (entityMetadata.getId() == 9) {
metadata.getFlags().setFlag(EntityFlag.SHOW_BOTTOM, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.SHOW_BOTTOM, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -329,6 +329,10 @@ public class Entity {
metadata.put(EntityData.BOUNDING_BOX_WIDTH, width); metadata.put(EntityData.BOUNDING_BOX_WIDTH, width);
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, height); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
break; break;
case 7:
//TODO check
metadata.put(EntityData.FREEZING_EFFECT_STRENGTH, entityMetadata.getValue());
break;
} }
} }

View File

@ -32,7 +32,7 @@ import org.geysermc.connector.network.session.GeyserSession;
public class ExpOrbEntity extends Entity { public class ExpOrbEntity extends Entity {
private int amount; private final int amount;
public ExpOrbEntity(int amount, long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { public ExpOrbEntity(int amount, long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
super(entityId, geyserId, entityType, position, motion, rotation); super(entityId, geyserId, entityType, position, motion, rotation);

View File

@ -55,7 +55,7 @@ public class FireworkEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
ItemStack item = (ItemStack) entityMetadata.getValue(); ItemStack item = (ItemStack) entityMetadata.getValue();
if (item == null) { if (item == null) {
return; return;
@ -134,7 +134,7 @@ public class FireworkEntity extends Entity {
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
builder.put("Fireworks", fireworksBuilder.build()); builder.put("Fireworks", fireworksBuilder.build());
metadata.put(EntityData.DISPLAY_ITEM, builder.build()); metadata.put(EntityData.DISPLAY_ITEM, builder.build());
} else if (entityMetadata.getId() == 8 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) { } else if (entityMetadata.getId() == 9 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) {
//Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too. //Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too.
PlayerEntity entity = session.getPlayerEntity(); PlayerEntity entity = session.getPlayerEntity();
float yaw = entity.getRotation().getX(); float yaw = entity.getRotation().getX();

View File

@ -67,7 +67,7 @@ public class FishingHookEntity extends ThrowableEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { // Hooked entity if (entityMetadata.getId() == 8) { // Hooked entity
int hookedEntityId = (int) entityMetadata.getValue() - 1; int hookedEntityId = (int) entityMetadata.getValue() - 1;
Entity entity = session.getEntityCache().getEntityByJavaId(hookedEntityId); Entity entity = session.getEntityCache().getEntityByJavaId(hookedEntityId);
if (entity == null && session.getPlayerEntity().getEntityId() == hookedEntityId) { if (entity == null && session.getPlayerEntity().getEntityId() == hookedEntityId) {

View File

@ -42,7 +42,7 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 13 && !showCustomBlock) { if (entityMetadata.getId() == 14 && !showCustomBlock) {
hasFuel = (boolean) entityMetadata.getValue(); hasFuel = (boolean) entityMetadata.getValue();
updateDefaultBlockMetadata(session); updateDefaultBlockMetadata(session);
} }

View File

@ -54,7 +54,7 @@ public class ItemEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
AddItemEntityPacket itemPacket = new AddItemEntityPacket(); AddItemEntityPacket itemPacket = new AddItemEntityPacket();
itemPacket.setRuntimeEntityId(geyserId); itemPacket.setRuntimeEntityId(geyserId);
itemPacket.setPosition(position.add(0d, this.entityType.getOffset(), 0d)); itemPacket.setPosition(position.add(0d, this.entityType.getOffset(), 0d));

View File

@ -105,7 +105,7 @@ public class ItemFrameEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) { if (entityMetadata.getId() == 8 && entityMetadata.getValue() != null) {
this.heldItem = (ItemStack) entityMetadata.getValue(); this.heldItem = (ItemStack) entityMetadata.getValue();
ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem); ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem);
ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue()); ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
@ -124,11 +124,11 @@ public class ItemFrameEntity extends Entity {
cachedTag = tag.build(); cachedTag = tag.build();
updateBlock(session); updateBlock(session);
} }
else if (entityMetadata.getId() == 7 && entityMetadata.getValue() == null && cachedTag != null) { else if (entityMetadata.getId() == 8 && entityMetadata.getValue() == null && cachedTag != null) {
cachedTag = getDefaultTag(); cachedTag = getDefaultTag();
updateBlock(session); updateBlock(session);
} }
else if (entityMetadata.getId() == 8) { else if (entityMetadata.getId() == 9) {
rotation = ((int) entityMetadata.getValue()) * 45; rotation = ((int) entityMetadata.getValue()) * 45;
if (cachedTag == null) { if (cachedTag == null) {
updateBlock(session); updateBlock(session);

View File

@ -68,7 +68,7 @@ public class LivingEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
switch (entityMetadata.getId()) { switch (entityMetadata.getId()) {
case 7: // blocking case 8: // blocking
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
//blocking gets triggered when using a bow, but if we set USING_ITEM for all items, it may look like //blocking gets triggered when using a bow, but if we set USING_ITEM for all items, it may look like
@ -81,16 +81,16 @@ public class LivingEntity extends Entity {
// Riptide spin attack // Riptide spin attack
metadata.getFlags().setFlag(EntityFlag.DAMAGE_NEARBY_MOBS, (xd & 0x04) == 0x04); metadata.getFlags().setFlag(EntityFlag.DAMAGE_NEARBY_MOBS, (xd & 0x04) == 0x04);
break; break;
case 8: case 9:
metadata.put(EntityData.HEALTH, entityMetadata.getValue()); metadata.put(EntityData.HEALTH, entityMetadata.getValue());
break; break;
case 9: case 10:
metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue()); metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue());
break; break;
case 10: case 11:
metadata.put(EntityData.EFFECT_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); metadata.put(EntityData.EFFECT_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
break; break;
case 13: // Bed Position case 14: // Bed Position
Position bedPosition = (Position) entityMetadata.getValue(); Position bedPosition = (Position) entityMetadata.getValue();
if (bedPosition != null) { if (bedPosition != null) {
metadata.put(EntityData.BED_POSITION, Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ())); metadata.put(EntityData.BED_POSITION, Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ()));

View File

@ -40,33 +40,33 @@ public class MinecartEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
metadata.put(EntityData.HEALTH, entityMetadata.getValue()); metadata.put(EntityData.HEALTH, entityMetadata.getValue());
} }
// Direction in which the minecart is shaking // Direction in which the minecart is shaking
if (entityMetadata.getId() == 8) { if (entityMetadata.getId() == 9) {
metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue()); metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue());
} }
// Power in Java, time in Bedrock // Power in Java, time in Bedrock
if (entityMetadata.getId() == 9) { if (entityMetadata.getId() == 10) {
metadata.put(EntityData.HURT_TIME, Math.min((int) (float) entityMetadata.getValue(), 15)); metadata.put(EntityData.HURT_TIME, Math.min((int) (float) entityMetadata.getValue(), 15));
} }
if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class
// Custom block // Custom block
if (entityMetadata.getId() == 10) { if (entityMetadata.getId() == 11) {
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue())); metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue()));
} }
// Custom block offset // Custom block offset
if (entityMetadata.getId() == 11) { if (entityMetadata.getId() == 12) {
metadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue()); metadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue());
} }
// If the custom block should be enabled // If the custom block should be enabled
if (entityMetadata.getId() == 12) { if (entityMetadata.getId() == 13) {
// Needs a byte based off of Java's boolean // Needs a byte based off of Java's boolean
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
} }

View File

@ -45,7 +45,7 @@ public class TNTEntity extends Entity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
currentTick = (int) entityMetadata.getValue(); currentTick = (int) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.IGNITED, true); metadata.getFlags().setFlag(EntityFlag.IGNITED, true);
metadata.put(EntityData.FUSE_LENGTH, currentTick); metadata.put(EntityData.FUSE_LENGTH, currentTick);

View File

@ -167,10 +167,8 @@ public class ThrowableEntity extends Entity implements Tickable {
*/ */
protected boolean isInWater(GeyserSession session) { protected boolean isInWater(GeyserSession session) {
if (session.getConnector().getConfig().isCacheChunks()) { if (session.getConnector().getConfig().isCacheChunks()) {
if (0 <= position.getFloorY() && position.getFloorY() <= 255) { int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt()); return BlockStateValues.getWaterLevel(block) != -1;
return BlockStateValues.getWaterLevel(block) != -1;
}
} }
return false; return false;
} }

View File

@ -51,7 +51,7 @@ public class ThrownPotionEntity extends ThrowableEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7 && entityMetadata.getType() == MetadataType.ITEM) { if (entityMetadata.getId() == 8 && entityMetadata.getType() == MetadataType.ITEM) {
ItemStack itemStack = (ItemStack) entityMetadata.getValue(); ItemStack itemStack = (ItemStack) entityMetadata.getValue();
ItemEntry itemEntry = ItemRegistry.getItem(itemStack); ItemEntry itemEntry = ItemRegistry.getItem(itemStack);
if (itemEntry.getJavaIdentifier().endsWith("potion") && itemStack.getNbt() != null) { if (itemEntry.getJavaIdentifier().endsWith("potion") && itemStack.getNbt() != null) {

View File

@ -44,17 +44,17 @@ public class TippedArrowEntity extends AbstractArrowEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Arrow potion effect color // Arrow potion effect color
if (entityMetadata.getId() == 9) { if (entityMetadata.getId() == 10) {
int potionColor = (int) entityMetadata.getValue(); int potionColor = (int) entityMetadata.getValue();
// -1 means no color // -1 means no color
if (potionColor == -1) { if (potionColor == -1) {
metadata.remove(EntityData.CUSTOM_DISPLAY); metadata.put(EntityData.CUSTOM_DISPLAY, 0);
} else { } else {
TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor); TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor);
if (potion != null && potion.getJavaColor() != -1) { if (potion != null && potion.getJavaColor() != -1) {
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) potion.getBedrockId()); metadata.put(EntityData.CUSTOM_DISPLAY, (byte) potion.getBedrockId());
} else { } else {
metadata.remove(EntityData.CUSTOM_DISPLAY); metadata.put(EntityData.CUSTOM_DISPLAY, 0);
} }
} }
} }

View File

@ -39,7 +39,7 @@ public class TridentEntity extends AbstractArrowEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 10) { if (entityMetadata.getId() == 11) {
metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue());
} }

View File

@ -46,7 +46,7 @@ public class WitherSkullEntity extends ItemedFireballEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 7) { if (entityMetadata.getId() == 8) {
boolean newIsCharged = (boolean) entityMetadata.getValue(); boolean newIsCharged = (boolean) entityMetadata.getValue();
if (newIsCharged != isCharged) { if (newIsCharged != isCharged) {
isCharged = newIsCharged; isCharged = newIsCharged;

View File

@ -40,7 +40,7 @@ public class AgeableEntity extends CreatureEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
boolean isBaby = (boolean) entityMetadata.getValue(); boolean isBaby = (boolean) entityMetadata.getValue();
metadata.put(EntityData.SCALE, isBaby ? .55f : 1f); metadata.put(EntityData.SCALE, isBaby ? .55f : 1f);
metadata.getFlags().setFlag(EntityFlag.BABY, isBaby); metadata.getFlags().setFlag(EntityFlag.BABY, isBaby);

View File

@ -126,7 +126,7 @@ public class ArmorStandEntity extends LivingEntity {
} }
} else if (entityMetadata.getId() == 2) { } else if (entityMetadata.getId() == 2) {
updateSecondEntityStatus(false); updateSecondEntityStatus(false);
} else if (entityMetadata.getId() == 14 && entityMetadata.getType() == MetadataType.BYTE) { } else if (entityMetadata.getId() == 15 && entityMetadata.getType() == MetadataType.BYTE) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
// isSmall // isSmall
@ -169,37 +169,37 @@ public class ArmorStandEntity extends LivingEntity {
EntityFlag negativeYToggle = null; EntityFlag negativeYToggle = null;
EntityFlag negativeZToggle = null; EntityFlag negativeZToggle = null;
switch (entityMetadata.getId()) { switch (entityMetadata.getId()) {
case 15: // Head case 16: // Head
dataLeech = EntityData.MARK_VARIANT; dataLeech = EntityData.MARK_VARIANT;
negativeXToggle = EntityFlag.INTERESTED; negativeXToggle = EntityFlag.INTERESTED;
negativeYToggle = EntityFlag.CHARGED; negativeYToggle = EntityFlag.CHARGED;
negativeZToggle = EntityFlag.POWERED; negativeZToggle = EntityFlag.POWERED;
break; break;
case 16: // Body case 17: // Body
dataLeech = EntityData.VARIANT; dataLeech = EntityData.VARIANT;
negativeXToggle = EntityFlag.IN_LOVE; negativeXToggle = EntityFlag.IN_LOVE;
negativeYToggle = EntityFlag.CELEBRATING; negativeYToggle = EntityFlag.CELEBRATING;
negativeZToggle = EntityFlag.CELEBRATING_SPECIAL; negativeZToggle = EntityFlag.CELEBRATING_SPECIAL;
break; break;
case 17: // Left arm case 18: // Left arm
dataLeech = EntityData.TRADE_TIER; dataLeech = EntityData.TRADE_TIER;
negativeXToggle = EntityFlag.CHARGING; negativeXToggle = EntityFlag.CHARGING;
negativeYToggle = EntityFlag.CRITICAL; negativeYToggle = EntityFlag.CRITICAL;
negativeZToggle = EntityFlag.DANCING; negativeZToggle = EntityFlag.DANCING;
break; break;
case 18: // Right arm case 19: // Right arm
dataLeech = EntityData.MAX_TRADE_TIER; dataLeech = EntityData.MAX_TRADE_TIER;
negativeXToggle = EntityFlag.ELDER; negativeXToggle = EntityFlag.ELDER;
negativeYToggle = EntityFlag.EMOTING; negativeYToggle = EntityFlag.EMOTING;
negativeZToggle = EntityFlag.IDLING; negativeZToggle = EntityFlag.IDLING;
break; break;
case 19: // Left leg case 20: // Left leg
dataLeech = EntityData.SKIN_ID; dataLeech = EntityData.SKIN_ID;
negativeXToggle = EntityFlag.IS_ILLAGER_CAPTAIN; negativeXToggle = EntityFlag.IS_ILLAGER_CAPTAIN;
negativeYToggle = EntityFlag.IS_IN_UI; negativeYToggle = EntityFlag.IS_IN_UI;
negativeZToggle = EntityFlag.LINGERING; negativeZToggle = EntityFlag.LINGERING;
break; break;
case 20: // Right leg case 21: // Right leg
dataLeech = EntityData.HURT_DIRECTION; dataLeech = EntityData.HURT_DIRECTION;
negativeXToggle = EntityFlag.IS_PREGNANT; negativeXToggle = EntityFlag.IS_PREGNANT;
negativeYToggle = EntityFlag.SHEARED; negativeYToggle = EntityFlag.SHEARED;

View File

@ -39,7 +39,7 @@ public class BatEntity extends AmbientEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.RESTING, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.RESTING, (xd & 0x01) == 0x01);
} }

View File

@ -41,7 +41,7 @@ public class InsentientEntity extends LivingEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 14 && entityMetadata.getType() == MetadataType.BYTE) { if (entityMetadata.getId() == 15 && entityMetadata.getType() == MetadataType.BYTE) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
} }

View File

@ -53,7 +53,7 @@ public class IronGolemEntity extends GolemEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
if (entityMetadata.getId() == 8) { if (entityMetadata.getId() == 9) {
// Required so the resource pack sees the entity health // Required so the resource pack sees the entity health
attributes.put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(metadata.getFloat(EntityData.HEALTH), 100f)); attributes.put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(metadata.getFloat(EntityData.HEALTH), 100f));
updateBedrockAttributes(session); updateBedrockAttributes(session);

View File

@ -39,7 +39,7 @@ public class SlimeEntity extends InsentientEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
this.metadata.put(EntityData.SCALE, 0.10f + (int) entityMetadata.getValue()); this.metadata.put(EntityData.SCALE, 0.10f + (int) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -39,7 +39,7 @@ public class SnowGolemEntity extends GolemEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
// Handle the visibility of the pumpkin // Handle the visibility of the pumpkin
metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) != 0x10); metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) != 0x10);

View File

@ -43,7 +43,7 @@ public class BeeEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
// Bee is performing sting attack; trigger animation // Bee is performing sting attack; trigger animation
if ((xd & 0x02) == 0x02) { if ((xd & 0x02) == 0x02) {
@ -58,7 +58,7 @@ public class BeeEntity extends AnimalEntity {
// If the bee has nectar or not // If the bee has nectar or not
metadata.getFlags().setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08); metadata.getFlags().setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08);
} }
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
// Converting "anger time" to a boolean // Converting "anger time" to a boolean
metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() > 0); metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() > 0);
} }

View File

@ -41,10 +41,10 @@ public class FoxEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
metadata.put(EntityData.VARIANT, entityMetadata.getValue()); metadata.put(EntityData.VARIANT, entityMetadata.getValue());
} }
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x04) == 0x04); metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x04) == 0x04);
@ -56,6 +56,6 @@ public class FoxEntity extends AnimalEntity {
@Override @Override
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemEntry itemEntry) { public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemEntry itemEntry) {
return javaIdentifierStripped.equals("sweet_berries"); return session.getTagCache().isFoxFood(itemEntry);
} }
} }

View File

@ -41,7 +41,7 @@ public class HoglinEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
// Immune to zombification? // Immune to zombification?
// Apply shaking effect if not in the nether and zombification is possible // Apply shaking effect if not in the nether and zombification is possible
metadata.getFlags().setFlag(EntityFlag.SHAKING, !((boolean) entityMetadata.getValue()) && !session.getDimension().equals(DimensionUtils.NETHER)); metadata.getFlags().setFlag(EntityFlag.SHAKING, !((boolean) entityMetadata.getValue()) && !session.getDimension().equals(DimensionUtils.NETHER));

View File

@ -39,7 +39,7 @@ public class MooshroomEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
metadata.put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0); metadata.put(EntityData.VARIANT, entityMetadata.getValue().equals("brown") ? 1 : 0);
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -40,7 +40,7 @@ public class OcelotEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
metadata.getFlags().setFlag(EntityFlag.TRUSTING, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.TRUSTING, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -47,7 +47,7 @@ public class PandaEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.EATING, (int) entityMetadata.getValue() > 0); metadata.getFlags().setFlag(EntityFlag.EATING, (int) entityMetadata.getValue() > 0);
metadata.put(EntityData.EATING_COUNTER, entityMetadata.getValue()); metadata.put(EntityData.EATING_COUNTER, entityMetadata.getValue());
if ((int) entityMetadata.getValue() != 0) { if ((int) entityMetadata.getValue() != 0) {
@ -59,15 +59,15 @@ public class PandaEntity extends AnimalEntity {
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
} }
if (entityMetadata.getId() == 19) { if (entityMetadata.getId() == 20) {
mainGene = (int) (byte) entityMetadata.getValue(); mainGene = (int) (byte) entityMetadata.getValue();
updateAppearance(); updateAppearance();
} }
if (entityMetadata.getId() == 20) { if (entityMetadata.getId() == 21) {
hiddenGene = (int) (byte) entityMetadata.getValue(); hiddenGene = (int) (byte) entityMetadata.getValue();
updateAppearance(); updateAppearance();
} }
if (entityMetadata.getId() == 21) { if (entityMetadata.getId() == 22) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.SNEEZING, (xd & 0x02) == 0x02); metadata.getFlags().setFlag(EntityFlag.SNEEZING, (xd & 0x02) == 0x02);
metadata.getFlags().setFlag(EntityFlag.ROLLING, (xd & 0x04) == 0x04); metadata.getFlags().setFlag(EntityFlag.ROLLING, (xd & 0x04) == 0x04);

View File

@ -40,8 +40,7 @@ public class PigEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 17) {
if (entityMetadata.getId() == 16) {
metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -40,7 +40,7 @@ public class PolarBearEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
metadata.getFlags().setFlag(EntityFlag.STANDING, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.STANDING, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -40,10 +40,11 @@ public class PufferFishEntity extends AbstractFishEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
// Transfers correctly but doesn't apply on the client // Transfers correctly but doesn't apply on the client
//TODO check - probably because we didn't set PUFFERFISH_SIZE as a byte
int puffsize = (int) entityMetadata.getValue(); int puffsize = (int) entityMetadata.getValue();
metadata.put(EntityData.PUFFERFISH_SIZE, puffsize); metadata.put(EntityData.PUFFERFISH_SIZE, (byte) puffsize);
metadata.put(EntityData.VARIANT, puffsize); metadata.put(EntityData.VARIANT, puffsize);
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -42,14 +42,14 @@ public class RabbitEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
metadata.put(EntityData.SCALE, .55f); metadata.put(EntityData.SCALE, .55f);
boolean isBaby = (boolean) entityMetadata.getValue(); boolean isBaby = (boolean) entityMetadata.getValue();
if (isBaby) { if (isBaby) {
metadata.put(EntityData.SCALE, .35f); metadata.put(EntityData.SCALE, .35f);
metadata.getFlags().setFlag(EntityFlag.BABY, true); metadata.getFlags().setFlag(EntityFlag.BABY, true);
} }
} else if (entityMetadata.getId() == 16) { } else if (entityMetadata.getId() == 17) {
int variant = (int) entityMetadata.getValue(); int variant = (int) entityMetadata.getValue();
// Change the killer bunny to display as white since it only exists on Java Edition // Change the killer bunny to display as white since it only exists on Java Edition

View File

@ -40,7 +40,7 @@ public class SheepEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) == 0x10);
metadata.put(EntityData.COLOR, xd); metadata.put(EntityData.COLOR, xd);

View File

@ -46,10 +46,10 @@ public class StriderEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
shaking = (boolean) entityMetadata.getValue(); shaking = (boolean) entityMetadata.getValue();
} }
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue());
} }

View File

@ -28,8 +28,6 @@ package org.geysermc.connector.entity.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.geysermc.connector.entity.living.AbstractFishEntity; import org.geysermc.connector.entity.living.AbstractFishEntity;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -42,34 +40,14 @@ public class TropicalFishEntity extends AbstractFishEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
TropicalFishVariant variant = TropicalFishVariant.fromVariantNumber((int) entityMetadata.getValue()); int varNumber = (int) entityMetadata.getValue();
metadata.put(EntityData.VARIANT, variant.getShape()); // Shape 0-1 metadata.put(EntityData.VARIANT, varNumber & 0xFF); // Shape 0-1
metadata.put(EntityData.MARK_VARIANT, variant.getPattern()); // Pattern 0-5 metadata.put(EntityData.MARK_VARIANT, (varNumber >> 8) & 0xFF); // Pattern 0-5
metadata.put(EntityData.COLOR, variant.getBaseColor()); // Base color 0-15 metadata.put(EntityData.COLOR, (byte) ((varNumber >> 16) & 0xFF)); // Base color 0-15
metadata.put(EntityData.COLOR_2, variant.getPatternColor()); // Pattern color 0-15 metadata.put(EntityData.COLOR_2, (byte) ((varNumber >> 24) & 0xFF)); // Pattern color 0-15
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
} }
@Getter
@AllArgsConstructor
private static class TropicalFishVariant {
private int shape;
private int pattern;
private byte baseColor;
private byte patternColor;
/**
* Convert the variant number from Java into separate values
*
* @param varNumber Variant number from Java edition
*
* @return The variant converted into TropicalFishVariant
*/
public static TropicalFishVariant fromVariantNumber(int varNumber) {
return new TropicalFishVariant((varNumber & 0xFF), ((varNumber >> 8) & 0xFF), (byte) ((varNumber >> 16) & 0xFF), (byte) ((varNumber >> 24) & 0xFF));
}
}
} }

View File

@ -40,9 +40,9 @@ public class TurtleEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
metadata.getFlags().setFlag(EntityFlag.IS_PREGNANT, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.IS_PREGNANT, (boolean) entityMetadata.getValue());
} else if (entityMetadata.getId() == 18) { } else if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.LAYING_EGG, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.LAYING_EGG, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -64,7 +64,7 @@ public class AbstractHorseEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.TAMED, (xd & 0x02) == 0x02); metadata.getFlags().setFlag(EntityFlag.TAMED, (xd & 0x02) == 0x02);
metadata.getFlags().setFlag(EntityFlag.SADDLED, (xd & 0x04) == 0x04); metadata.getFlags().setFlag(EntityFlag.SADDLED, (xd & 0x04) == 0x04);
@ -106,7 +106,7 @@ public class AbstractHorseEntity extends AnimalEntity {
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
if (entityMetadata.getId() == 8) { if (entityMetadata.getId() == 9) {
// Update the health attribute // Update the health attribute
updateBedrockAttributes(session); updateBedrockAttributes(session);
} }

View File

@ -42,7 +42,7 @@ public class ChestedHorseEntity extends AbstractHorseEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.CHESTED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.CHESTED, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -39,7 +39,7 @@ public class HorseEntity extends AbstractHorseEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.put(EntityData.VARIANT, entityMetadata.getValue()); metadata.put(EntityData.VARIANT, entityMetadata.getValue());
metadata.put(EntityData.MARK_VARIANT, (((int) entityMetadata.getValue()) >> 8) % 5); metadata.put(EntityData.MARK_VARIANT, (((int) entityMetadata.getValue()) >> 8) % 5);
} }

View File

@ -46,11 +46,11 @@ public class LlamaEntity extends ChestedHorseEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Strength // Strength
if (entityMetadata.getId() == 19) { if (entityMetadata.getId() == 20) {
metadata.put(EntityData.STRENGTH, entityMetadata.getValue()); metadata.put(EntityData.STRENGTH, entityMetadata.getValue());
} }
// Color equipped on the llama // Color equipped on the llama
if (entityMetadata.getId() == 20) { if (entityMetadata.getId() == 21) {
// Bedrock treats llama decoration as armor // Bedrock treats llama decoration as armor
MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket(); MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket();
equipmentPacket.setRuntimeEntityId(geyserId); equipmentPacket.setRuntimeEntityId(geyserId);
@ -71,7 +71,7 @@ public class LlamaEntity extends ChestedHorseEntity {
session.sendUpstreamPacket(equipmentPacket); session.sendUpstreamPacket(equipmentPacket);
} }
// Color of the llama // Color of the llama
if (entityMetadata.getId() == 21) { if (entityMetadata.getId() == 22) {
metadata.put(EntityData.VARIANT, entityMetadata.getValue()); metadata.put(EntityData.VARIANT, entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -49,13 +49,13 @@ public class CatEntity extends TameableEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
// Update collar color if tamed // Update collar color if tamed
if (metadata.getFlags().getFlag(EntityFlag.TAMED)) { if (metadata.getFlags().getFlag(EntityFlag.TAMED)) {
metadata.put(EntityData.COLOR, collarColor); metadata.put(EntityData.COLOR, collarColor);
} }
} }
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
// Different colors in Java and Bedrock for some reason // Different colors in Java and Bedrock for some reason
int variantColor; int variantColor;
switch ((int) entityMetadata.getValue()) { switch ((int) entityMetadata.getValue()) {
@ -76,7 +76,7 @@ public class CatEntity extends TameableEntity {
} }
metadata.put(EntityData.VARIANT, variantColor); metadata.put(EntityData.VARIANT, variantColor);
} }
if (entityMetadata.getId() == 21) { if (entityMetadata.getId() == 22) {
collarColor = (byte) (int) entityMetadata.getValue(); collarColor = (byte) (int) entityMetadata.getValue();
// Needed or else wild cats are a red color // Needed or else wild cats are a red color
if (metadata.getFlags().getFlag(EntityFlag.TAMED)) { if (metadata.getFlags().getFlag(EntityFlag.TAMED)) {

View File

@ -41,7 +41,7 @@ public class ParrotEntity extends TameableEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Parrot color // Parrot color
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.put(EntityData.VARIANT, entityMetadata.getValue()); metadata.put(EntityData.VARIANT, entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -44,7 +44,7 @@ public class TameableEntity extends AnimalEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 0x02) == 0x02); metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 0x02) == 0x02);
@ -52,7 +52,7 @@ public class TameableEntity extends AnimalEntity {
} }
// Note: Must be set for wolf collar color to work // Note: Must be set for wolf collar color to work
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
if (entityMetadata.getValue() != null) { if (entityMetadata.getValue() != null) {
// Owner UUID of entity // Owner UUID of entity
Entity entity = session.getEntityCache().getPlayerEntity((UUID) entityMetadata.getValue()); Entity entity = session.getEntityCache().getPlayerEntity((UUID) entityMetadata.getValue());

View File

@ -54,7 +54,7 @@ public class WolfEntity extends TameableEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
//Reset wolf color //Reset wolf color
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
boolean angry = (xd & 0x02) == 0x02; boolean angry = (xd & 0x02) == 0x02;
if (angry) { if (angry) {
@ -63,13 +63,13 @@ public class WolfEntity extends TameableEntity {
} }
// "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head // "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue());
} }
// Wolf collar color // Wolf collar color
// Relies on EntityData.OWNER_EID being set in TameableEntity.java // Relies on EntityData.OWNER_EID being set in TameableEntity.java
if (entityMetadata.getId() == 19 && !metadata.getFlags().getFlag(EntityFlag.ANGRY)) { if (entityMetadata.getId() == 20 && !metadata.getFlags().getFlag(EntityFlag.ANGRY)) {
metadata.put(EntityData.COLOR, collarColor = (byte) (int) entityMetadata.getValue()); metadata.put(EntityData.COLOR, collarColor = (byte) (int) entityMetadata.getValue());
if (!metadata.containsKey(EntityData.OWNER_EID)) { if (!metadata.containsKey(EntityData.OWNER_EID)) {
// If a color is set and there is no owner entity ID, set one. // If a color is set and there is no owner entity ID, set one.
@ -79,7 +79,7 @@ public class WolfEntity extends TameableEntity {
} }
// Wolf anger (1.16+) // Wolf anger (1.16+)
if (entityMetadata.getId() == 20) { if (entityMetadata.getId() == 21) {
metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() != 0); metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() != 0);
metadata.put(EntityData.COLOR, (int) entityMetadata.getValue() != 0 ? (byte) 0 : collarColor); metadata.put(EntityData.COLOR, (int) entityMetadata.getValue() != 0 ? (byte) 0 : collarColor);
} }

View File

@ -85,7 +85,7 @@ public class VillagerEntity extends AbstractMerchantEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
VillagerData villagerData = (VillagerData) entityMetadata.getValue(); VillagerData villagerData = (VillagerData) entityMetadata.getValue();
// Profession // Profession
metadata.put(EntityData.VARIANT, VILLAGER_VARIANTS.get(villagerData.getProfession())); metadata.put(EntityData.VARIANT, VILLAGER_VARIANTS.get(villagerData.getProfession()));

View File

@ -39,7 +39,7 @@ public class AbstractSkeletonEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 14) { if (entityMetadata.getId() == 15) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
// A bit of a loophole so the hands get raised - set the target ID to its own ID // A bit of a loophole so the hands get raised - set the target ID to its own ID
metadata.put(EntityData.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0); metadata.put(EntityData.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0);

View File

@ -40,7 +40,7 @@ public class BasePiglinEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
// Immune to zombification? // Immune to zombification?
// Apply shaking effect if not in the nether and zombification is possible // Apply shaking effect if not in the nether and zombification is possible
metadata.getFlags().setFlag(EntityFlag.SHAKING, !((boolean) entityMetadata.getValue()) && !session.getDimension().equals(DimensionUtils.NETHER)); metadata.getFlags().setFlag(EntityFlag.SHAKING, !((boolean) entityMetadata.getValue()) && !session.getDimension().equals(DimensionUtils.NETHER));

View File

@ -39,7 +39,7 @@ public class BlazeEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01);
} }

View File

@ -45,15 +45,15 @@ public class CreeperEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
if (!ignitedByFlintAndSteel) { if (!ignitedByFlintAndSteel) {
metadata.getFlags().setFlag(EntityFlag.IGNITED, (int) entityMetadata.getValue() == 1); metadata.getFlags().setFlag(EntityFlag.IGNITED, (int) entityMetadata.getValue() == 1);
} }
} }
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
metadata.getFlags().setFlag(EntityFlag.POWERED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.POWERED, (boolean) entityMetadata.getValue());
} }
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
ignitedByFlintAndSteel = (boolean) entityMetadata.getValue(); ignitedByFlintAndSteel = (boolean) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.IGNITED, ignitedByFlintAndSteel); metadata.getFlags().setFlag(EntityFlag.IGNITED, ignitedByFlintAndSteel);
} }

View File

@ -92,7 +92,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { // Phase if (entityMetadata.getId() == 16) { // Phase
phase = (int) entityMetadata.getValue(); phase = (int) entityMetadata.getValue();
phaseTicks = 0; phaseTicks = 0;
metadata.getFlags().setFlag(EntityFlag.SITTING, isSitting()); metadata.getFlags().setFlag(EntityFlag.SITTING, isSitting());
@ -100,7 +100,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
if (entityMetadata.getId() == 8) { // Health if (entityMetadata.getId() == 9) { // Health
// Update the health attribute, so that the death animation gets played // Update the health attribute, so that the death animation gets played
// Round health up, so that Bedrock doesn't consider the dragon to be dead when health is between 0 and 1 // Round health up, so that Bedrock doesn't consider the dragon to be dead when health is between 0 and 1
float health = (float) Math.ceil(metadata.getFloat(EntityData.HEALTH)); float health = (float) Math.ceil(metadata.getFloat(EntityData.HEALTH));

View File

@ -43,11 +43,11 @@ public class EndermanEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Held block // Held block
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
metadata.put(EntityData.CARRIED_BLOCK, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue())); metadata.put(EntityData.CARRIED_BLOCK, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue()));
} }
// "Is screaming" - controls sound // "Is screaming" - controls sound
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
if ((boolean) entityMetadata.getValue()) { if ((boolean) entityMetadata.getValue()) {
LevelSoundEvent2Packet packet = new LevelSoundEvent2Packet(); LevelSoundEvent2Packet packet = new LevelSoundEvent2Packet();
packet.setSound(SoundEvent.STARE); packet.setSound(SoundEvent.STARE);
@ -58,7 +58,7 @@ public class EndermanEntity extends MonsterEntity {
} }
} }
// "Is staring/provoked" - controls visuals // "Is staring/provoked" - controls visuals
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
metadata.getFlags().setFlag(EntityFlag.ANGRY, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.ANGRY, (boolean) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

View File

@ -40,7 +40,7 @@ public class GhastEntity extends FlyingEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
// If the ghast is attacking // If the ghast is attacking
metadata.put(EntityData.CHARGE_AMOUNT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); metadata.put(EntityData.CHARGE_AMOUNT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
} }

View File

@ -40,7 +40,7 @@ public class GuardianEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue()); Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue());
if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue()) { if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue()) {
entity = session.getPlayerEntity(); entity = session.getPlayerEntity();

View File

@ -41,17 +41,17 @@ public class PiglinEntity extends BasePiglinEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
boolean isBaby = (boolean) entityMetadata.getValue(); boolean isBaby = (boolean) entityMetadata.getValue();
if (isBaby) { if (isBaby) {
metadata.put(EntityData.SCALE, .55f); metadata.put(EntityData.SCALE, .55f);
metadata.getFlags().setFlag(EntityFlag.BABY, true); metadata.getFlags().setFlag(EntityFlag.BABY, true);
} }
} }
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 18) {
metadata.getFlags().setFlag(EntityFlag.CHARGING, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.CHARGING, (boolean) entityMetadata.getValue());
} }
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.DANCING, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.DANCING, (boolean) entityMetadata.getValue());
} }

View File

@ -26,10 +26,8 @@
package org.geysermc.connector.entity.living.monster; package org.geysermc.connector.entity.living.monster;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.connector.entity.living.GolemEntity; import org.geysermc.connector.entity.living.GolemEntity;
@ -46,16 +44,17 @@ public class ShulkerEntity extends GolemEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
BlockFace blockFace = (BlockFace) entityMetadata.getValue(); BlockFace blockFace = (BlockFace) entityMetadata.getValue();
metadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) blockFace.ordinal()); metadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) blockFace.ordinal());
} }
if (entityMetadata.getId() == 16) { //TODO - this was removed on Java Edition, but does Bedrock Edition still need it??
Position position = (Position) entityMetadata.getValue(); // if (entityMetadata.getId() == 16) {
if (position != null) { // Position position = (Position) entityMetadata.getValue();
metadata.put(EntityData.SHULKER_ATTACH_POS, Vector3i.from(position.getX(), position.getY(), position.getZ())); // if (position != null) {
} // metadata.put(EntityData.SHULKER_ATTACH_POS, Vector3i.from(position.getX(), position.getY(), position.getZ()));
} // }
// }
if (entityMetadata.getId() == 17) { if (entityMetadata.getId() == 17) {
int height = (byte) entityMetadata.getValue(); int height = (byte) entityMetadata.getValue();

View File

@ -39,7 +39,7 @@ public class SpiderEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.WALL_CLIMBING, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.WALL_CLIMBING, (xd & 0x01) == 0x01);
} }

View File

@ -39,7 +39,7 @@ public class VexEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
// Set the target to the player to force the attack animation // Set the target to the player to force the attack animation
// even if the player isn't the target as we dont get the target on Java // even if the player isn't the target as we dont get the target on Java

View File

@ -44,7 +44,7 @@ public class WitherEntity extends MonsterEntity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
long targetID = 0; long targetID = 0;
if (entityMetadata.getId() >= 15 && entityMetadata.getId() <= 17) { if (entityMetadata.getId() >= 16 && entityMetadata.getId() <= 18) {
Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue()); Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue());
if (entity == null && session.getPlayerEntity().getEntityId() == (int) entityMetadata.getValue()) { if (entity == null && session.getPlayerEntity().getEntityId() == (int) entityMetadata.getValue()) {
entity = session.getPlayerEntity(); entity = session.getPlayerEntity();
@ -55,13 +55,13 @@ public class WitherEntity extends MonsterEntity {
} }
} }
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
metadata.put(EntityData.WITHER_TARGET_1, targetID); metadata.put(EntityData.WITHER_TARGET_1, targetID);
} else if (entityMetadata.getId() == 16) {
metadata.put(EntityData.WITHER_TARGET_2, targetID);
} else if (entityMetadata.getId() == 17) { } else if (entityMetadata.getId() == 17) {
metadata.put(EntityData.WITHER_TARGET_3, targetID); metadata.put(EntityData.WITHER_TARGET_2, targetID);
} else if (entityMetadata.getId() == 18) { } else if (entityMetadata.getId() == 18) {
metadata.put(EntityData.WITHER_TARGET_3, targetID);
} else if (entityMetadata.getId() == 19) {
metadata.put(EntityData.WITHER_INVULNERABLE_TICKS, entityMetadata.getValue()); metadata.put(EntityData.WITHER_INVULNERABLE_TICKS, entityMetadata.getValue());
// Show the shield for the first few seconds of spawning (like Java) // Show the shield for the first few seconds of spawning (like Java)

View File

@ -40,7 +40,7 @@ public class ZoglinEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
boolean isBaby = (boolean) entityMetadata.getValue(); boolean isBaby = (boolean) entityMetadata.getValue();
if (isBaby) { if (isBaby) {
metadata.put(EntityData.SCALE, .55f); metadata.put(EntityData.SCALE, .55f);

View File

@ -40,7 +40,7 @@ public class ZombieEntity extends MonsterEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 16) {
boolean isBaby = (boolean) entityMetadata.getValue(); boolean isBaby = (boolean) entityMetadata.getValue();
if (isBaby) { if (isBaby) {
metadata.put(EntityData.SCALE, .55f); metadata.put(EntityData.SCALE, .55f);

View File

@ -42,11 +42,11 @@ public class ZombieVillagerEntity extends ZombieEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
metadata.getFlags().setFlag(EntityFlag.IS_TRANSFORMING, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.IS_TRANSFORMING, (boolean) entityMetadata.getValue());
metadata.getFlags().setFlag(EntityFlag.SHAKING, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.SHAKING, (boolean) entityMetadata.getValue());
} }
if (entityMetadata.getId() == 19) { if (entityMetadata.getId() == 20) {
VillagerData villagerData = (VillagerData) entityMetadata.getValue(); VillagerData villagerData = (VillagerData) entityMetadata.getValue();
// Region - only one used on Bedrock // Region - only one used on Bedrock
metadata.put(EntityData.MARK_VARIANT, VillagerEntity.VILLAGER_REGIONS.get(villagerData.getType())); metadata.put(EntityData.MARK_VARIANT, VillagerEntity.VILLAGER_REGIONS.get(villagerData.getType()));

View File

@ -45,7 +45,7 @@ public class SpellcasterIllagerEntity extends AbstractIllagerEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
int spellType = (int) (byte) entityMetadata.getValue(); int spellType = (int) (byte) entityMetadata.getValue();
// Summon vex, attack, or wololo // Summon vex, attack, or wololo
metadata.getFlags().setFlag(EntityFlag.CASTING, spellType == 1 || spellType == 2 || spellType == 3); metadata.getFlags().setFlag(EntityFlag.CASTING, spellType == 1 || spellType == 2 || spellType == 3);

View File

@ -40,7 +40,7 @@ public class VindicatorEntity extends AbstractIllagerEntity {
@Override @Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
// Allow the axe to be shown if necessary // Allow the axe to be shown if necessary
if (entityMetadata.getId() == 14) { if (entityMetadata.getId() == 15) {
byte xd = (byte) entityMetadata.getValue(); byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 4) == 4); metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 4) == 4);
} }

View File

@ -273,7 +273,7 @@ public class PlayerEntity extends LivingEntity {
} }
// Extra hearts - is not metadata but an attribute on Bedrock // Extra hearts - is not metadata but an attribute on Bedrock
if (entityMetadata.getId() == 14) { if (entityMetadata.getId() == 15) {
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
attributesPacket.setRuntimeEntityId(geyserId); attributesPacket.setRuntimeEntityId(geyserId);
List<AttributeData> attributes = new ArrayList<>(); List<AttributeData> attributes = new ArrayList<>();
@ -283,7 +283,7 @@ public class PlayerEntity extends LivingEntity {
session.sendUpstreamPacket(attributesPacket); session.sendUpstreamPacket(attributesPacket);
} }
if (entityMetadata.getId() == 16) { if (entityMetadata.getId() == 17) {
// OptionalPack usage for toggling skin bits // OptionalPack usage for toggling skin bits
// In Java Edition, a bit being set means that part should be enabled // In Java Edition, a bit being set means that part should be enabled
// However, to ensure that the pack still works on other servers, we invert the bit so all values by default // However, to ensure that the pack still works on other servers, we invert the bit so all values by default
@ -292,10 +292,10 @@ public class PlayerEntity extends LivingEntity {
} }
// Parrot occupying shoulder // Parrot occupying shoulder
if (entityMetadata.getId() == 18 || entityMetadata.getId() == 19) { if (entityMetadata.getId() == 19 || entityMetadata.getId() == 20) {
CompoundTag tag = (CompoundTag) entityMetadata.getValue(); CompoundTag tag = (CompoundTag) entityMetadata.getValue();
if (tag != null && !tag.isEmpty()) { if (tag != null && !tag.isEmpty()) {
if ((entityMetadata.getId() == 18 && leftParrot != null) || (entityMetadata.getId() == 19 && rightParrot != null)) { if ((entityMetadata.getId() == 19 && leftParrot != null) || (entityMetadata.getId() == 20 && rightParrot != null)) {
// No need to update a parrot's data when it already exists // No need to update a parrot's data when it already exists
return; return;
} }
@ -321,10 +321,10 @@ public class PlayerEntity extends LivingEntity {
rightParrot = parrot; rightParrot = parrot;
} }
} else { } else {
Entity parrot = (entityMetadata.getId() == 18 ? leftParrot : rightParrot); Entity parrot = (entityMetadata.getId() == 19 ? leftParrot : rightParrot);
if (parrot != null) { if (parrot != null) {
parrot.despawnEntity(session); parrot.despawnEntity(session);
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 19) {
leftParrot = null; leftParrot = null;
} else { } else {
rightParrot = null; rightParrot = null;

View File

@ -29,17 +29,18 @@ 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.chunk.Column;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import lombok.Setter;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.MathUtils; import org.geysermc.connector.utils.MathUtils;
public class ChunkCache { public class ChunkCache {
private static final int MINIMUM_WORLD_HEIGHT = 0;
private final boolean cache; private final boolean cache;
private final Long2ObjectMap<Column> chunks; private final Long2ObjectMap<Column> chunks;
@Setter
private int minY;
public ChunkCache(GeyserSession session) { public ChunkCache(GeyserSession session) {
if (session.getConnector().getWorldManager().hasOwnChunkCache()) { if (session.getConnector().getWorldManager().hasOwnChunkCache()) {
this.cache = false; // To prevent Spigot from initializing this.cache = false; // To prevent Spigot from initializing
@ -87,7 +88,7 @@ public class ChunkCache {
return; return;
} }
if (y < MINIMUM_WORLD_HEIGHT || (y >> 4) > column.getChunks().length - 1) { if (y < minY || (y >> 4) > column.getChunks().length - 1) {
// Y likely goes above or below the height limit of this world // Y likely goes above or below the height limit of this world
return; return;
} }
@ -108,7 +109,7 @@ public class ChunkCache {
return BlockTranslator.JAVA_AIR_ID; return BlockTranslator.JAVA_AIR_ID;
} }
if (y < MINIMUM_WORLD_HEIGHT || (y >> 4) > column.getChunks().length - 1) { if (y < minY || (y >> 4) > column.getChunks().length - 1) {
// Y likely goes above or below the height limit of this world // Y likely goes above or below the height limit of this world
return BlockTranslator.JAVA_AIR_ID; return BlockTranslator.JAVA_AIR_ID;
} }

View File

@ -39,24 +39,51 @@ import java.util.Map;
*/ */
public class TagCache { public class TagCache {
/* Blocks */ /* Blocks */
private IntList wool = IntLists.emptyList(); private IntList leaves;
private IntList wool;
private IntList axeEffective;
private IntList hoeEffective;
private IntList pickaxeEffective;
private IntList shovelEffective;
/* Items */ /* Items */
private IntList flowers = IntLists.emptyList(); private IntList flowers;
private IntList piglinLoved = IntLists.emptyList(); private IntList foxFood;
private IntList piglinLoved;
public TagCache() {
// Ensure all lists are non-null
clear();
}
public void loadPacket(ServerDeclareTagsPacket packet) { public void loadPacket(ServerDeclareTagsPacket packet) {
Map<String, int[]> blockTags = packet.getBlockTags(); Map<String, int[]> blockTags = packet.getTags().get("minecraft:block");
this.leaves = IntList.of(blockTags.get("minecraft:leaves"));
this.wool = IntList.of(blockTags.get("minecraft:wool")); this.wool = IntList.of(blockTags.get("minecraft:wool"));
Map<String, int[]> itemTags = packet.getItemTags(); this.axeEffective = IntList.of(blockTags.get("minecraft:mineable/axe"));
this.hoeEffective = IntList.of(blockTags.get("minecraft:mineable/hoe"));
this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe"));
this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel"));
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
this.flowers = IntList.of(itemTags.get("minecraft:flowers")); this.flowers = IntList.of(itemTags.get("minecraft:flowers"));
this.foxFood = IntList.of(itemTags.get("minecraft:fox_food"));
this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved")); this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved"));
} }
public void clear() { public void clear() {
this.leaves = IntLists.emptyList();
this.wool = IntLists.emptyList(); this.wool = IntLists.emptyList();
this.axeEffective = IntLists.emptyList();
this.hoeEffective = IntLists.emptyList();
this.pickaxeEffective = IntLists.emptyList();
this.shovelEffective = IntLists.emptyList();
this.flowers = IntLists.emptyList(); this.flowers = IntLists.emptyList();
this.foxFood = IntLists.emptyList();
this.piglinLoved = IntLists.emptyList(); this.piglinLoved = IntLists.emptyList();
} }
@ -64,11 +91,32 @@ public class TagCache {
return flowers.contains(itemEntry.getJavaId()); return flowers.contains(itemEntry.getJavaId());
} }
public boolean isFoxFood(ItemEntry itemEntry) {
return foxFood.contains(itemEntry.getJavaId());
}
public boolean shouldPiglinAdmire(ItemEntry itemEntry) { public boolean shouldPiglinAdmire(ItemEntry itemEntry) {
return piglinLoved.contains(itemEntry.getJavaId()); return piglinLoved.contains(itemEntry.getJavaId());
} }
public boolean isWool(BlockMapping blockMapping) { public boolean isAxeEffective(BlockMapping blockMapping) {
return wool.contains(blockMapping.getJavaBlockId()); return axeEffective.contains(blockMapping.getJavaBlockId());
}
public boolean isHoeEffective(BlockMapping blockMapping) {
return hoeEffective.contains(blockMapping.getJavaBlockId());
}
public boolean isPickaxeEffective(BlockMapping blockMapping) {
return pickaxeEffective.contains(blockMapping.getJavaBlockId());
}
public boolean isShovelEffective(BlockMapping blockMapping) {
return shovelEffective.contains(blockMapping.getJavaBlockId());
}
public boolean isShearsEffective(BlockMapping blockMapping) {
int javaBlockId = blockMapping.getJavaBlockId();
return leaves.contains(javaBlockId) || wool.contains(javaBlockId);
} }
} }

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2019-2021 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;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientPongPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPingPacket;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator;
// Why does this packet exist? Whatever, we better implement it
@Translator(packet = ServerPingPacket.class)
public class JavaPingPacket extends PacketTranslator<ServerPingPacket> {
@Override
public void translate(ServerPingPacket packet, GeyserSession session) {
session.sendDownstreamPacket(new ClientPongPacket(packet.getId()));
}
}

View File

@ -25,8 +25,6 @@
package org.geysermc.connector.network.translators.world; package org.geysermc.connector.network.translators.world;
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.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
@ -53,45 +51,12 @@ public class GeyserWorldManager extends WorldManager {
return BlockTranslator.JAVA_AIR_ID; return BlockTranslator.JAVA_AIR_ID;
} }
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
ChunkCache chunkCache = session.getChunkCache();
Column cachedColumn;
Chunk cachedChunk;
if (chunkCache == null || (cachedColumn = chunkCache.getChunk(x, z)) == null || (cachedChunk = cachedColumn.getChunks()[y]) == null) {
return;
}
// Copy state IDs from cached chunk to output chunk
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
chunk.set(blockX, blockY, blockZ, cachedChunk.get(blockX, blockY, blockZ));
}
}
}
}
@Override @Override
public boolean hasOwnChunkCache() { public boolean hasOwnChunkCache() {
// This implementation can only fetch data from the session chunk cache // This implementation can only fetch data from the session chunk cache
return false; return false;
} }
@Override
public int[] getBiomeDataAt(GeyserSession session, int x, int z) {
if (session.getConnector().getConfig().isCacheChunks()) {
ChunkCache chunkCache = session.getChunkCache();
if (chunkCache != null) { // Chunk cache can be null if the session is closed asynchronously
Column column = chunkCache.getChunk(x, z);
if (column != null) { // Column can be null if the server sent a partial chunk update before the first ground-up-continuous one
return column.getBiomeData();
}
}
}
return new int[1024];
}
@Override @Override
public NbtMap getLecternDataAt(GeyserSession session, int x, int y, int z, boolean isChunkLoad) { public NbtMap getLecternDataAt(GeyserSession session, int x, int y, int z, boolean isChunkLoad) {
// Without direct server access, we can't get lectern information on-the-fly. // Without direct server access, we can't get lectern information on-the-fly.

View File

@ -25,7 +25,6 @@
package org.geysermc.connector.network.translators.world; package org.geysermc.connector.network.translators.world;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
@ -76,17 +75,6 @@ public abstract class WorldManager {
*/ */
public abstract int getBlockAt(GeyserSession session, int x, int y, int z); public abstract int getBlockAt(GeyserSession session, int x, int y, int z);
/**
* Gets all block states in the specified chunk section.
*
* @param session the session
* @param x the chunk's X coordinate
* @param y the chunk's Y coordinate
* @param z the chunk's Z coordinate
* @param section the chunk section to store the block data in
*/
public abstract void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk section);
/** /**
* Checks whether or not this world manager requires a separate chunk cache/has access to more block data than the chunk cache. * Checks whether or not this world manager requires a separate chunk cache/has access to more block data than the chunk cache.
* <p> * <p>
@ -97,16 +85,6 @@ public abstract class WorldManager {
*/ */
public abstract boolean hasOwnChunkCache(); public abstract boolean hasOwnChunkCache();
/**
* Gets the Java biome data for the specified chunk.
*
* @param session the session of the player
* @param x the chunk's X coordinate
* @param z the chunk's Z coordinate
* @return the biome data for the specified region with a length of 1024.
*/
public abstract int[] getBiomeDataAt(GeyserSession session, int x, int z);
/** /**
* Sigh. <br> * Sigh. <br>
* *

View File

@ -143,12 +143,7 @@ public abstract class BlockTranslator {
builder.canBreakWithHand(false); builder.canBreakWithHand(false);
} }
JsonNode toolTypeNode = entry.getValue().get("tool_type"); builder.toolType(""); //TODO
if (toolTypeNode != null) {
builder.toolType(toolTypeNode.textValue());
} else {
builder.toolType("");
}
JsonNode collisionIndexNode = entry.getValue().get("collision_index"); JsonNode collisionIndexNode = entry.getValue().get("collision_index");
if (hardnessNode != null) { if (hardnessNode != null) {
@ -225,7 +220,7 @@ public abstract class BlockTranslator {
throw new AssertionError("Unable to find Java water in palette"); throw new AssertionError("Unable to find Java water in palette");
} }
JAVA_WATER_ID = waterRuntimeId; JAVA_WATER_ID = waterRuntimeId;
BlockMapping.AIR = JAVA_RUNTIME_ID_TO_BLOCK_MAPPING.get(JAVA_AIR_ID); BlockMapping.AIR = JAVA_RUNTIME_ID_TO_BLOCK_MAPPING.get(JAVA_AIR_ID);
BlockTranslator1_16_210.init(); BlockTranslator1_16_210.init();

View File

@ -41,16 +41,28 @@ public class BlockUtils {
*/ */
public static final Position POSITION_ZERO = new Position(0, 0, 0); public static final Position POSITION_ZERO = new Position(0, 0, 0);
private static boolean correctTool(String blockToolType, String itemToolType) { private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
return (blockToolType.equals("sword") && itemToolType.equals("sword")) || switch (itemToolType) {
(blockToolType.equals("shovel") && itemToolType.equals("shovel")) || case "axe":
(blockToolType.equals("pickaxe") && itemToolType.equals("pickaxe")) || return session.getTagCache().isAxeEffective(blockMapping);
(blockToolType.equals("axe") && itemToolType.equals("axe")) || case "hoe":
(blockToolType.equals("shears") && itemToolType.equals("shears")); return session.getTagCache().isHoeEffective(blockMapping);
case "pickaxe":
return session.getTagCache().isPickaxeEffective(blockMapping);
case "shears":
return session.getTagCache().isShearsEffective(blockMapping);
case "shovel":
return session.getTagCache().isShovelEffective(blockMapping);
case "sword":
return blockMapping.getJavaBlockId() == BlockTranslator.JAVA_COBWEB_BLOCK_ID;
default:
session.getConnector().getLogger().warning("Unknown tool type: " + itemToolType);
return false;
}
} }
private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isWoolBlock) { private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isShearsEffective) {
if (toolType.equals("shears")) return isWoolBlock ? 5.0 : 15.0; if (toolType.equals("shears")) return isShearsEffective ? 5.0 : 15.0;
if (toolType.equals("")) return 1.0; if (toolType.equals("")) return 1.0;
switch (toolTier) { switch (toolTier) {
// https://minecraft.gamepedia.com/Breaking#Speed // https://minecraft.gamepedia.com/Breaking#Speed
@ -73,16 +85,14 @@ public class BlockUtils {
//http://minecraft.gamepedia.com/Breaking //http://minecraft.gamepedia.com/Breaking
private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool, private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool,
String toolType, boolean isWoolBlock, boolean isCobweb, int toolEfficiencyLevel, int hasteLevel, int miningFatigueLevel, String toolType, boolean isShearsEffective, int toolEfficiencyLevel, int hasteLevel, int miningFatigueLevel,
boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround, boolean insideWaterAndNotOnGround) { boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround, boolean insideWaterAndNotOnGround) {
double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness; double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness;
double speed = 1.0 / baseTime; double speed = 1.0 / baseTime;
if (correctTool) { if (correctTool) {
speed *= toolBreakTimeBonus(toolType, toolTier, isWoolBlock); speed *= toolBreakTimeBonus(toolType, toolTier, isShearsEffective);
speed += toolEfficiencyLevel == 0 ? 0 : toolEfficiencyLevel * toolEfficiencyLevel + 1; speed += toolEfficiencyLevel == 0 ? 0 : toolEfficiencyLevel * toolEfficiencyLevel + 1;
} else if (toolType.equals("sword")) {
speed*= (isCobweb ? 15.0 : 1.5);
} }
speed *= 1.0 + (0.2 * hasteLevel); speed *= 1.0 + (0.2 * hasteLevel);
@ -110,9 +120,7 @@ public class BlockUtils {
} }
public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemEntry item, CompoundTag nbtData, boolean isSessionPlayer) { public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemEntry item, CompoundTag nbtData, boolean isSessionPlayer) {
boolean isWoolBlock = session.getTagCache().isWool(blockMapping); boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice
boolean isCobweb = blockMapping.getJavaBlockId() == BlockTranslator.JAVA_COBWEB_BLOCK_ID;
String blockToolType = blockMapping.getToolType();
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand(); boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
String toolType = ""; String toolType = "";
String toolTier = ""; String toolTier = "";
@ -121,7 +129,7 @@ public class BlockUtils {
ToolItemEntry toolItem = (ToolItemEntry) item; ToolItemEntry toolItem = (ToolItemEntry) item;
toolType = toolItem.getToolType(); toolType = toolItem.getToolType();
toolTier = toolItem.getToolTier(); toolTier = toolItem.getToolTier();
correctTool = correctTool(blockToolType, toolType); correctTool = correctTool(session, blockMapping, toolType);
} }
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency"); int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency");
int hasteLevel = 0; int hasteLevel = 0;
@ -129,8 +137,8 @@ public class BlockUtils {
if (!isSessionPlayer) { if (!isSessionPlayer) {
// Another entity is currently mining; we have all the information we know // Another entity is currently mining; we have all the information we know
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock, return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective,
isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false,
false, false); false, false);
} }
@ -144,8 +152,8 @@ public class BlockUtils {
boolean outOfWaterButNotOnGround = (!isInWater) && (!session.getPlayerEntity().isOnGround()); boolean outOfWaterButNotOnGround = (!isInWater) && (!session.getPlayerEntity().isOnGround());
boolean insideWaterNotOnGround = isInWater && !session.getPlayerEntity().isOnGround(); boolean insideWaterNotOnGround = isInWater && !session.getPlayerEntity().isOnGround();
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock, return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective,
isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity,
outOfWaterButNotOnGround, insideWaterNotOnGround); outOfWaterButNotOnGround, insideWaterNotOnGround);
} }

View File

@ -82,7 +82,17 @@ public class ChunkUtils {
public static ChunkData translateToBedrock(GeyserSession session, Column column) { public static ChunkData translateToBedrock(GeyserSession session, Column column) {
Chunk[] javaSections = column.getChunks(); Chunk[] javaSections = column.getChunks();
ChunkSection[] sections = new ChunkSection[javaSections.length];
//FIXME TEMPORARY UNTIL THE CAVES AND CLIFFS EXPERIMENTAL DATA IS REMOVED UNLESS IT'S NOT REMOVED THEN HMMMM
int sectionYOffset;
if (session.getDimension().equals(DimensionUtils.OVERWORLD)) {
sectionYOffset = 4;
} else {
sectionYOffset = 0;
}
//FIXME END
ChunkSection[] sections = new ChunkSection[javaSections.length + sectionYOffset];
// Temporarily stores compound tags of Bedrock-only block entities // Temporarily stores compound tags of Bedrock-only block entities
List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>(); List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>();
@ -195,7 +205,7 @@ public class ChunkUtils {
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) }; layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
} }
sections[sectionY] = new ChunkSection(layers); sections[sectionY + sectionYOffset] = new ChunkSection(layers);
} }
CompoundTag[] blockEntities = column.getTileEntities(); CompoundTag[] blockEntities = column.getTileEntities();