Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +01:00
21w20a support
Dieser Commit ist enthalten in:
Ursprung
024655f008
Commit
b5307ab3ed
@ -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!
|
||||
|
||||
### 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
|
||||
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
|
||||
- Structure block UI
|
||||
|
||||
Extended height features can be "supported", but require additional work.
|
||||
|
||||
## What can't be fixed
|
||||
The following things cannot be fixed without changes to Bedrock. As of now, they are not fixable in Geyser.
|
||||
|
||||
|
@ -150,11 +150,6 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||
if (isLegacy)
|
||||
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");
|
||||
// Set if we need to use a different method for getting a player's locale
|
||||
SpigotCommandSender.setUseLegacyLocaleMethod(isPre1_12);
|
||||
@ -170,11 +165,11 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||
this.geyserWorldManager = new GeyserSpigot1_12NativeWorldManager(this);
|
||||
} else {
|
||||
// Post-1.13
|
||||
this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this, use3dBiomes);
|
||||
this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this);
|
||||
}
|
||||
} else {
|
||||
// No ViaVersion
|
||||
this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, use3dBiomes);
|
||||
this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this);
|
||||
}
|
||||
geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion);
|
||||
} catch (Exception e) {
|
||||
@ -196,7 +191,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||
this.geyserWorldManager = new GeyserSpigotFallbackWorldManager(this);
|
||||
} else {
|
||||
// Post-1.13
|
||||
this.geyserWorldManager = new GeyserSpigotWorldManager(this, use3dBiomes);
|
||||
this.geyserWorldManager = new GeyserSpigotWorldManager(this);
|
||||
}
|
||||
geyserLogger.debug("Using default world manager: " + this.geyserWorldManager.getClass());
|
||||
}
|
||||
|
@ -25,9 +25,7 @@
|
||||
|
||||
package org.geysermc.platform.spigot.world.manager;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -63,7 +61,7 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
|
||||
private final List<Pair<Integer, Protocol>> protocolList;
|
||||
|
||||
public GeyserSpigot1_12WorldManager(Plugin plugin) {
|
||||
super(plugin, false);
|
||||
super(plugin);
|
||||
this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
|
||||
this.protocolList = ProtocolRegistry.getProtocolPath(CLIENT_PROTOCOL_VERSION,
|
||||
ProtocolVersion.v1_13.getVersion());
|
||||
@ -117,28 +115,6 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
|
||||
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
|
||||
public boolean isLegacy() {
|
||||
return true;
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.platform.spigot.world.manager;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
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 GeyserSpigotFallbackWorldManager(Plugin plugin) {
|
||||
// Since this is pre-1.13 (and thus pre-1.15), there will never be 3D biomes.
|
||||
super(plugin, false);
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,11 +44,6 @@ public class GeyserSpigotFallbackWorldManager extends GeyserSpigotWorldManager {
|
||||
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
|
||||
public boolean hasOwnChunkCache() {
|
||||
return false;
|
||||
|
@ -46,8 +46,8 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl
|
||||
|
||||
private final Int2IntMap oldToNewBlockId;
|
||||
|
||||
public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin, boolean use3dBiomes) {
|
||||
super(plugin, use3dBiomes);
|
||||
public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin) {
|
||||
super(plugin);
|
||||
IntList allBlockStates = adapter.getAllBlockStates();
|
||||
oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size());
|
||||
ProtocolVersion serverVersion = plugin.getServerProtocolVersion();
|
||||
|
@ -36,8 +36,8 @@ import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
|
||||
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
||||
protected final SpigotWorldAdapter adapter;
|
||||
|
||||
public GeyserSpigotNativeWorldManager(Plugin plugin, boolean use3dBiomes) {
|
||||
super(plugin, use3dBiomes);
|
||||
public GeyserSpigotNativeWorldManager(Plugin plugin) {
|
||||
super(plugin);
|
||||
adapter = SpigotAdapters.getWorldAdapter();
|
||||
}
|
||||
|
||||
|
@ -25,18 +25,13 @@
|
||||
|
||||
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.data.game.chunk.Chunk;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtMapBuilder;
|
||||
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.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Lectern;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@ -44,17 +39,13 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.inventory.translators.LecternInventoryTranslator;
|
||||
import org.geysermc.connector.network.translators.world.GeyserWorldManager;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.utils.BlockEntityUtils;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.GameRule;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -67,48 +58,10 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||
*/
|
||||
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;
|
||||
|
||||
public GeyserSpigotWorldManager(Plugin plugin, boolean use3dBiomes) {
|
||||
this.use3dBiomes = use3dBiomes;
|
||||
public GeyserSpigotWorldManager(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
|
||||
@ -121,64 +74,11 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||
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
|
||||
public boolean hasOwnChunkCache() {
|
||||
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
|
||||
public NbtMap getLecternDataAt(GeyserSession session, int x, int y, int z, boolean isChunkLoad) {
|
||||
// Run as a task to prevent async issues
|
||||
|
@ -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
|
||||
}
|
@ -122,7 +122,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.steveice10</groupId>
|
||||
<artifactId>mcprotocollib</artifactId>
|
||||
<version>21w17a-SNAPSHOT</version>
|
||||
<version>21w20a-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
@ -44,7 +44,7 @@ public class AbstractArrowEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
byte data = (byte) entityMetadata.getValue();
|
||||
|
||||
metadata.getFlags().setFlag(EntityFlag.CRITICAL, (data & 0x01) == 0x01);
|
||||
|
@ -52,12 +52,12 @@ public class AreaEffectCloudEntity extends Entity {
|
||||
|
||||
@Override
|
||||
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.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());
|
||||
} else if (entityMetadata.getId() == 10) {
|
||||
} else if (entityMetadata.getId() == 11) {
|
||||
Particle particle = (Particle) entityMetadata.getValue();
|
||||
int particleId = EffectRegistry.getParticleId(particle.getType());
|
||||
if (particleId != -1) {
|
||||
|
@ -87,24 +87,24 @@ public class BoatEntity extends Entity {
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
|
||||
// Time since last hit
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
metadata.put(EntityData.HURT_TIME, entityMetadata.getValue());
|
||||
}
|
||||
|
||||
// Rocking direction
|
||||
if (entityMetadata.getId() == 8) {
|
||||
if (entityMetadata.getId() == 9) {
|
||||
metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue());
|
||||
}
|
||||
|
||||
// 'Health' in Bedrock, damage taken in Java
|
||||
if (entityMetadata.getId() == 9) {
|
||||
if (entityMetadata.getId() == 10) {
|
||||
// Not exactly health but it makes motion in Bedrock
|
||||
metadata.put(EntityData.HEALTH, 40 - ((int) (float) entityMetadata.getValue()));
|
||||
}
|
||||
|
||||
if (entityMetadata.getId() == 10) {
|
||||
if (entityMetadata.getId() == 11) {
|
||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
||||
} else if (entityMetadata.getId() == 11) {
|
||||
} else if (entityMetadata.getId() == 12) {
|
||||
isPaddlingLeft = (boolean) entityMetadata.getValue();
|
||||
if (isPaddlingLeft) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
else if (entityMetadata.getId() == 12) {
|
||||
else if (entityMetadata.getId() == 13) {
|
||||
isPaddlingRight = (boolean) entityMetadata.getValue();
|
||||
if (isPaddlingRight) {
|
||||
paddleTimeRight = 0f;
|
||||
@ -139,7 +139,7 @@ public class BoatEntity extends Entity {
|
||||
} else {
|
||||
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?
|
||||
metadata.put(EntityData.BOAT_BUBBLE_TIME, entityMetadata.getValue());
|
||||
}
|
||||
|
@ -46,10 +46,10 @@ public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 13) {
|
||||
if (entityMetadata.getId() == 14) {
|
||||
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()));
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -56,7 +56,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
|
||||
// Custom block
|
||||
if (entityMetadata.getId() == 10) {
|
||||
if (entityMetadata.getId() == 11) {
|
||||
customBlock = (int) entityMetadata.getValue();
|
||||
|
||||
if (showCustomBlock) {
|
||||
@ -65,7 +65,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
|
||||
}
|
||||
|
||||
// Custom block offset
|
||||
if (entityMetadata.getId() == 11) {
|
||||
if (entityMetadata.getId() == 12) {
|
||||
customBlockOffset = (int) entityMetadata.getValue();
|
||||
|
||||
if (showCustomBlock) {
|
||||
@ -74,7 +74,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
|
||||
}
|
||||
|
||||
// If the custom block should be enabled
|
||||
if (entityMetadata.getId() == 12) {
|
||||
if (entityMetadata.getId() == 13) {
|
||||
if ((boolean) entityMetadata.getValue()) {
|
||||
showCustomBlock = true;
|
||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId(customBlock));
|
||||
|
@ -47,7 +47,7 @@ public class EnderCrystalEntity extends Entity {
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
// Show beam
|
||||
// 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) {
|
||||
Position pos = (Position) entityMetadata.getValue();
|
||||
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
|
||||
if (entityMetadata.getId() == 8) {
|
||||
if (entityMetadata.getId() == 9) {
|
||||
metadata.getFlags().setFlag(EntityFlag.SHOW_BOTTOM, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -329,6 +329,10 @@ public class Entity {
|
||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, width);
|
||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
|
||||
break;
|
||||
case 7:
|
||||
//TODO check
|
||||
metadata.put(EntityData.FREEZING_EFFECT_STRENGTH, entityMetadata.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
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) {
|
||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||
|
@ -55,7 +55,7 @@ public class FireworkEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
ItemStack item = (ItemStack) entityMetadata.getValue();
|
||||
if (item == null) {
|
||||
return;
|
||||
@ -134,7 +134,7 @@ public class FireworkEntity extends Entity {
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.put("Fireworks", fireworksBuilder.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.
|
||||
PlayerEntity entity = session.getPlayerEntity();
|
||||
float yaw = entity.getRotation().getX();
|
||||
|
@ -67,7 +67,7 @@ public class FishingHookEntity extends ThrowableEntity {
|
||||
|
||||
@Override
|
||||
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;
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId(hookedEntityId);
|
||||
if (entity == null && session.getPlayerEntity().getEntityId() == hookedEntityId) {
|
||||
|
@ -42,7 +42,7 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 13 && !showCustomBlock) {
|
||||
if (entityMetadata.getId() == 14 && !showCustomBlock) {
|
||||
hasFuel = (boolean) entityMetadata.getValue();
|
||||
updateDefaultBlockMetadata(session);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class ItemEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
AddItemEntityPacket itemPacket = new AddItemEntityPacket();
|
||||
itemPacket.setRuntimeEntityId(geyserId);
|
||||
itemPacket.setPosition(position.add(0d, this.entityType.getOffset(), 0d));
|
||||
|
@ -105,7 +105,7 @@ public class ItemFrameEntity extends Entity {
|
||||
|
||||
@Override
|
||||
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();
|
||||
ItemData itemData = ItemTranslator.translateToBedrock(session, heldItem);
|
||||
ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
|
||||
@ -124,11 +124,11 @@ public class ItemFrameEntity extends Entity {
|
||||
cachedTag = tag.build();
|
||||
updateBlock(session);
|
||||
}
|
||||
else if (entityMetadata.getId() == 7 && entityMetadata.getValue() == null && cachedTag != null) {
|
||||
else if (entityMetadata.getId() == 8 && entityMetadata.getValue() == null && cachedTag != null) {
|
||||
cachedTag = getDefaultTag();
|
||||
updateBlock(session);
|
||||
}
|
||||
else if (entityMetadata.getId() == 8) {
|
||||
else if (entityMetadata.getId() == 9) {
|
||||
rotation = ((int) entityMetadata.getValue()) * 45;
|
||||
if (cachedTag == null) {
|
||||
updateBlock(session);
|
||||
|
@ -68,7 +68,7 @@ public class LivingEntity extends Entity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
switch (entityMetadata.getId()) {
|
||||
case 7: // blocking
|
||||
case 8: // blocking
|
||||
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
|
||||
@ -81,16 +81,16 @@ public class LivingEntity extends Entity {
|
||||
// Riptide spin attack
|
||||
metadata.getFlags().setFlag(EntityFlag.DAMAGE_NEARBY_MOBS, (xd & 0x04) == 0x04);
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
metadata.put(EntityData.HEALTH, entityMetadata.getValue());
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
metadata.put(EntityData.EFFECT_COLOR, entityMetadata.getValue());
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
metadata.put(EntityData.EFFECT_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
||||
break;
|
||||
case 13: // Bed Position
|
||||
case 14: // Bed Position
|
||||
Position bedPosition = (Position) entityMetadata.getValue();
|
||||
if (bedPosition != null) {
|
||||
metadata.put(EntityData.BED_POSITION, Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ()));
|
||||
|
@ -40,33 +40,33 @@ public class MinecartEntity extends Entity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
metadata.put(EntityData.HEALTH, entityMetadata.getValue());
|
||||
}
|
||||
|
||||
// Direction in which the minecart is shaking
|
||||
if (entityMetadata.getId() == 8) {
|
||||
if (entityMetadata.getId() == 9) {
|
||||
metadata.put(EntityData.HURT_DIRECTION, entityMetadata.getValue());
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class
|
||||
// Custom block
|
||||
if (entityMetadata.getId() == 10) {
|
||||
if (entityMetadata.getId() == 11) {
|
||||
metadata.put(EntityData.DISPLAY_ITEM, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue()));
|
||||
}
|
||||
|
||||
// Custom block offset
|
||||
if (entityMetadata.getId() == 11) {
|
||||
if (entityMetadata.getId() == 12) {
|
||||
metadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue());
|
||||
}
|
||||
|
||||
// If the custom block should be enabled
|
||||
if (entityMetadata.getId() == 12) {
|
||||
if (entityMetadata.getId() == 13) {
|
||||
// Needs a byte based off of Java's boolean
|
||||
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class TNTEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
currentTick = (int) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.IGNITED, true);
|
||||
metadata.put(EntityData.FUSE_LENGTH, currentTick);
|
||||
|
@ -167,10 +167,8 @@ public class ThrowableEntity extends Entity implements Tickable {
|
||||
*/
|
||||
protected boolean isInWater(GeyserSession session) {
|
||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
||||
if (0 <= position.getFloorY() && position.getFloorY() <= 255) {
|
||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||
return BlockStateValues.getWaterLevel(block) != -1;
|
||||
}
|
||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||
return BlockStateValues.getWaterLevel(block) != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class ThrownPotionEntity extends ThrowableEntity {
|
||||
|
||||
@Override
|
||||
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();
|
||||
ItemEntry itemEntry = ItemRegistry.getItem(itemStack);
|
||||
if (itemEntry.getJavaIdentifier().endsWith("potion") && itemStack.getNbt() != null) {
|
||||
|
@ -44,17 +44,17 @@ public class TippedArrowEntity extends AbstractArrowEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
// Arrow potion effect color
|
||||
if (entityMetadata.getId() == 9) {
|
||||
if (entityMetadata.getId() == 10) {
|
||||
int potionColor = (int) entityMetadata.getValue();
|
||||
// -1 means no color
|
||||
if (potionColor == -1) {
|
||||
metadata.remove(EntityData.CUSTOM_DISPLAY);
|
||||
metadata.put(EntityData.CUSTOM_DISPLAY, 0);
|
||||
} else {
|
||||
TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor);
|
||||
if (potion != null && potion.getJavaColor() != -1) {
|
||||
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) potion.getBedrockId());
|
||||
} else {
|
||||
metadata.remove(EntityData.CUSTOM_DISPLAY);
|
||||
metadata.put(EntityData.CUSTOM_DISPLAY, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class TridentEntity extends AbstractArrowEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 10) {
|
||||
if (entityMetadata.getId() == 11) {
|
||||
metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ public class WitherSkullEntity extends ItemedFireballEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 7) {
|
||||
if (entityMetadata.getId() == 8) {
|
||||
boolean newIsCharged = (boolean) entityMetadata.getValue();
|
||||
if (newIsCharged != isCharged) {
|
||||
isCharged = newIsCharged;
|
||||
|
@ -40,7 +40,7 @@ public class AgeableEntity extends CreatureEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
||||
metadata.put(EntityData.SCALE, isBaby ? .55f : 1f);
|
||||
metadata.getFlags().setFlag(EntityFlag.BABY, isBaby);
|
||||
|
@ -126,7 +126,7 @@ public class ArmorStandEntity extends LivingEntity {
|
||||
}
|
||||
} else if (entityMetadata.getId() == 2) {
|
||||
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();
|
||||
|
||||
// isSmall
|
||||
@ -169,37 +169,37 @@ public class ArmorStandEntity extends LivingEntity {
|
||||
EntityFlag negativeYToggle = null;
|
||||
EntityFlag negativeZToggle = null;
|
||||
switch (entityMetadata.getId()) {
|
||||
case 15: // Head
|
||||
case 16: // Head
|
||||
dataLeech = EntityData.MARK_VARIANT;
|
||||
negativeXToggle = EntityFlag.INTERESTED;
|
||||
negativeYToggle = EntityFlag.CHARGED;
|
||||
negativeZToggle = EntityFlag.POWERED;
|
||||
break;
|
||||
case 16: // Body
|
||||
case 17: // Body
|
||||
dataLeech = EntityData.VARIANT;
|
||||
negativeXToggle = EntityFlag.IN_LOVE;
|
||||
negativeYToggle = EntityFlag.CELEBRATING;
|
||||
negativeZToggle = EntityFlag.CELEBRATING_SPECIAL;
|
||||
break;
|
||||
case 17: // Left arm
|
||||
case 18: // Left arm
|
||||
dataLeech = EntityData.TRADE_TIER;
|
||||
negativeXToggle = EntityFlag.CHARGING;
|
||||
negativeYToggle = EntityFlag.CRITICAL;
|
||||
negativeZToggle = EntityFlag.DANCING;
|
||||
break;
|
||||
case 18: // Right arm
|
||||
case 19: // Right arm
|
||||
dataLeech = EntityData.MAX_TRADE_TIER;
|
||||
negativeXToggle = EntityFlag.ELDER;
|
||||
negativeYToggle = EntityFlag.EMOTING;
|
||||
negativeZToggle = EntityFlag.IDLING;
|
||||
break;
|
||||
case 19: // Left leg
|
||||
case 20: // Left leg
|
||||
dataLeech = EntityData.SKIN_ID;
|
||||
negativeXToggle = EntityFlag.IS_ILLAGER_CAPTAIN;
|
||||
negativeYToggle = EntityFlag.IS_IN_UI;
|
||||
negativeZToggle = EntityFlag.LINGERING;
|
||||
break;
|
||||
case 20: // Right leg
|
||||
case 21: // Right leg
|
||||
dataLeech = EntityData.HURT_DIRECTION;
|
||||
negativeXToggle = EntityFlag.IS_PREGNANT;
|
||||
negativeYToggle = EntityFlag.SHEARED;
|
||||
|
@ -39,7 +39,7 @@ public class BatEntity extends AmbientEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.RESTING, (xd & 0x01) == 0x01);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class InsentientEntity extends LivingEntity {
|
||||
|
||||
@Override
|
||||
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();
|
||||
metadata.getFlags().setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class IronGolemEntity extends GolemEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
if (entityMetadata.getId() == 8) {
|
||||
if (entityMetadata.getId() == 9) {
|
||||
// Required so the resource pack sees the entity health
|
||||
attributes.put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(metadata.getFloat(EntityData.HEALTH), 100f));
|
||||
updateBedrockAttributes(session);
|
||||
|
@ -39,7 +39,7 @@ public class SlimeEntity extends InsentientEntity {
|
||||
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -39,7 +39,7 @@ public class SnowGolemEntity extends GolemEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
// Handle the visibility of the pumpkin
|
||||
metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) != 0x10);
|
||||
|
@ -43,7 +43,7 @@ public class BeeEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
// Bee is performing sting attack; trigger animation
|
||||
if ((xd & 0x02) == 0x02) {
|
||||
@ -58,7 +58,7 @@ public class BeeEntity extends AnimalEntity {
|
||||
// If the bee has nectar or not
|
||||
metadata.getFlags().setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08);
|
||||
}
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
// Converting "anger time" to a boolean
|
||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() > 0);
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ public class FoxEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
||||
}
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
|
||||
metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x04) == 0x04);
|
||||
@ -56,6 +56,6 @@ public class FoxEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemEntry itemEntry) {
|
||||
return javaIdentifierStripped.equals("sweet_berries");
|
||||
return session.getTagCache().isFoxFood(itemEntry);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class HoglinEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
// Immune to zombification?
|
||||
// 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));
|
||||
|
@ -39,7 +39,7 @@ public class MooshroomEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -40,7 +40,7 @@ public class OcelotEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
metadata.getFlags().setFlag(EntityFlag.TRUSTING, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -47,7 +47,7 @@ public class PandaEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
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.put(EntityData.EATING_COUNTER, entityMetadata.getValue());
|
||||
if ((int) entityMetadata.getValue() != 0) {
|
||||
@ -59,15 +59,15 @@ public class PandaEntity extends AnimalEntity {
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
if (entityMetadata.getId() == 19) {
|
||||
if (entityMetadata.getId() == 20) {
|
||||
mainGene = (int) (byte) entityMetadata.getValue();
|
||||
updateAppearance();
|
||||
}
|
||||
if (entityMetadata.getId() == 20) {
|
||||
if (entityMetadata.getId() == 21) {
|
||||
hiddenGene = (int) (byte) entityMetadata.getValue();
|
||||
updateAppearance();
|
||||
}
|
||||
if (entityMetadata.getId() == 21) {
|
||||
if (entityMetadata.getId() == 22) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.SNEEZING, (xd & 0x02) == 0x02);
|
||||
metadata.getFlags().setFlag(EntityFlag.ROLLING, (xd & 0x04) == 0x04);
|
||||
|
@ -40,8 +40,7 @@ public class PigEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -40,7 +40,7 @@ public class PolarBearEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
metadata.getFlags().setFlag(EntityFlag.STANDING, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -40,10 +40,11 @@ public class PufferFishEntity extends AbstractFishEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
// 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();
|
||||
metadata.put(EntityData.PUFFERFISH_SIZE, puffsize);
|
||||
metadata.put(EntityData.PUFFERFISH_SIZE, (byte) puffsize);
|
||||
metadata.put(EntityData.VARIANT, puffsize);
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -42,14 +42,14 @@ public class RabbitEntity extends AnimalEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
metadata.put(EntityData.SCALE, .55f);
|
||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
||||
if (isBaby) {
|
||||
metadata.put(EntityData.SCALE, .35f);
|
||||
metadata.getFlags().setFlag(EntityFlag.BABY, true);
|
||||
}
|
||||
} else if (entityMetadata.getId() == 16) {
|
||||
} else if (entityMetadata.getId() == 17) {
|
||||
int variant = (int) entityMetadata.getValue();
|
||||
|
||||
// Change the killer bunny to display as white since it only exists on Java Edition
|
||||
|
@ -40,7 +40,7 @@ public class SheepEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.SHEARED, (xd & 0x10) == 0x10);
|
||||
metadata.put(EntityData.COLOR, xd);
|
||||
|
@ -46,10 +46,10 @@ public class StriderEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
shaking = (boolean) entityMetadata.getValue();
|
||||
}
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,6 @@ package org.geysermc.connector.entity.living.animal;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
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.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
@ -42,34 +40,14 @@ public class TropicalFishEntity extends AbstractFishEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
TropicalFishVariant variant = TropicalFishVariant.fromVariantNumber((int) entityMetadata.getValue());
|
||||
if (entityMetadata.getId() == 17) {
|
||||
int varNumber = (int) entityMetadata.getValue();
|
||||
|
||||
metadata.put(EntityData.VARIANT, variant.getShape()); // Shape 0-1
|
||||
metadata.put(EntityData.MARK_VARIANT, variant.getPattern()); // Pattern 0-5
|
||||
metadata.put(EntityData.COLOR, variant.getBaseColor()); // Base color 0-15
|
||||
metadata.put(EntityData.COLOR_2, variant.getPatternColor()); // Pattern color 0-15
|
||||
metadata.put(EntityData.VARIANT, varNumber & 0xFF); // Shape 0-1
|
||||
metadata.put(EntityData.MARK_VARIANT, (varNumber >> 8) & 0xFF); // Pattern 0-5
|
||||
metadata.put(EntityData.COLOR, (byte) ((varNumber >> 16) & 0xFF)); // Base color 0-15
|
||||
metadata.put(EntityData.COLOR_2, (byte) ((varNumber >> 24) & 0xFF)); // Pattern color 0-15
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ public class TurtleEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
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());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -64,7 +64,7 @@ public class AbstractHorseEntity extends AnimalEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.TAMED, (xd & 0x02) == 0x02);
|
||||
metadata.getFlags().setFlag(EntityFlag.SADDLED, (xd & 0x04) == 0x04);
|
||||
@ -106,7 +106,7 @@ public class AbstractHorseEntity extends AnimalEntity {
|
||||
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
||||
if (entityMetadata.getId() == 8) {
|
||||
if (entityMetadata.getId() == 9) {
|
||||
// Update the health attribute
|
||||
updateBedrockAttributes(session);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class ChestedHorseEntity extends AbstractHorseEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
metadata.getFlags().setFlag(EntityFlag.CHESTED, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -39,7 +39,7 @@ public class HorseEntity extends AbstractHorseEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
||||
metadata.put(EntityData.MARK_VARIANT, (((int) entityMetadata.getValue()) >> 8) % 5);
|
||||
}
|
||||
|
@ -46,11 +46,11 @@ public class LlamaEntity extends ChestedHorseEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
// Strength
|
||||
if (entityMetadata.getId() == 19) {
|
||||
if (entityMetadata.getId() == 20) {
|
||||
metadata.put(EntityData.STRENGTH, entityMetadata.getValue());
|
||||
}
|
||||
// Color equipped on the llama
|
||||
if (entityMetadata.getId() == 20) {
|
||||
if (entityMetadata.getId() == 21) {
|
||||
// Bedrock treats llama decoration as armor
|
||||
MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket();
|
||||
equipmentPacket.setRuntimeEntityId(geyserId);
|
||||
@ -71,7 +71,7 @@ public class LlamaEntity extends ChestedHorseEntity {
|
||||
session.sendUpstreamPacket(equipmentPacket);
|
||||
}
|
||||
// Color of the llama
|
||||
if (entityMetadata.getId() == 21) {
|
||||
if (entityMetadata.getId() == 22) {
|
||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -49,13 +49,13 @@ public class CatEntity extends TameableEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
// Update collar color if tamed
|
||||
if (metadata.getFlags().getFlag(EntityFlag.TAMED)) {
|
||||
metadata.put(EntityData.COLOR, collarColor);
|
||||
}
|
||||
}
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
// Different colors in Java and Bedrock for some reason
|
||||
int variantColor;
|
||||
switch ((int) entityMetadata.getValue()) {
|
||||
@ -76,7 +76,7 @@ public class CatEntity extends TameableEntity {
|
||||
}
|
||||
metadata.put(EntityData.VARIANT, variantColor);
|
||||
}
|
||||
if (entityMetadata.getId() == 21) {
|
||||
if (entityMetadata.getId() == 22) {
|
||||
collarColor = (byte) (int) entityMetadata.getValue();
|
||||
// Needed or else wild cats are a red color
|
||||
if (metadata.getFlags().getFlag(EntityFlag.TAMED)) {
|
||||
|
@ -41,7 +41,7 @@ public class ParrotEntity extends TameableEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
// Parrot color
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -44,7 +44,7 @@ public class TameableEntity extends AnimalEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.SITTING, (xd & 0x01) == 0x01);
|
||||
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
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getValue() != null) {
|
||||
// Owner UUID of entity
|
||||
Entity entity = session.getEntityCache().getPlayerEntity((UUID) entityMetadata.getValue());
|
||||
|
@ -54,7 +54,7 @@ public class WolfEntity extends TameableEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
//Reset wolf color
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
boolean angry = (xd & 0x02) == 0x02;
|
||||
if (angry) {
|
||||
@ -63,13 +63,13 @@ public class WolfEntity extends TameableEntity {
|
||||
}
|
||||
|
||||
// "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());
|
||||
}
|
||||
|
||||
// Wolf collar color
|
||||
// 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());
|
||||
if (!metadata.containsKey(EntityData.OWNER_EID)) {
|
||||
// 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+)
|
||||
if (entityMetadata.getId() == 20) {
|
||||
if (entityMetadata.getId() == 21) {
|
||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (int) entityMetadata.getValue() != 0);
|
||||
metadata.put(EntityData.COLOR, (int) entityMetadata.getValue() != 0 ? (byte) 0 : collarColor);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public class VillagerEntity extends AbstractMerchantEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
VillagerData villagerData = (VillagerData) entityMetadata.getValue();
|
||||
// Profession
|
||||
metadata.put(EntityData.VARIANT, VILLAGER_VARIANTS.get(villagerData.getProfession()));
|
||||
|
@ -39,7 +39,7 @@ public class AbstractSkeletonEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 14) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
// 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);
|
||||
|
@ -40,7 +40,7 @@ public class BasePiglinEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
// Immune to zombification?
|
||||
// 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));
|
||||
|
@ -39,7 +39,7 @@ public class BlazeEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01);
|
||||
}
|
||||
|
@ -45,15 +45,15 @@ public class CreeperEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (!ignitedByFlintAndSteel) {
|
||||
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());
|
||||
}
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
ignitedByFlintAndSteel = (boolean) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.IGNITED, ignitedByFlintAndSteel);
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) { // Phase
|
||||
if (entityMetadata.getId() == 16) { // Phase
|
||||
phase = (int) entityMetadata.getValue();
|
||||
phaseTicks = 0;
|
||||
metadata.getFlags().setFlag(EntityFlag.SITTING, isSitting());
|
||||
@ -100,7 +100,7 @@ public class EnderDragonEntity extends InsentientEntity implements Tickable {
|
||||
|
||||
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
|
||||
// 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));
|
||||
|
@ -43,11 +43,11 @@ public class EndermanEntity extends MonsterEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
// Held block
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
metadata.put(EntityData.CARRIED_BLOCK, session.getBlockTranslator().getBedrockBlockId((int) entityMetadata.getValue()));
|
||||
}
|
||||
// "Is screaming" - controls sound
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if ((boolean) entityMetadata.getValue()) {
|
||||
LevelSoundEvent2Packet packet = new LevelSoundEvent2Packet();
|
||||
packet.setSound(SoundEvent.STARE);
|
||||
@ -58,7 +58,7 @@ public class EndermanEntity extends MonsterEntity {
|
||||
}
|
||||
}
|
||||
// "Is staring/provoked" - controls visuals
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -40,7 +40,7 @@ public class GhastEntity extends FlyingEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
// If the ghast is attacking
|
||||
metadata.put(EntityData.CHARGE_AMOUNT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class GuardianEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue());
|
||||
if (entity == null && session.getPlayerEntity().getEntityId() == (Integer) entityMetadata.getValue()) {
|
||||
entity = session.getPlayerEntity();
|
||||
|
@ -41,17 +41,17 @@ public class PiglinEntity extends BasePiglinEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
||||
if (isBaby) {
|
||||
metadata.put(EntityData.SCALE, .55f);
|
||||
metadata.getFlags().setFlag(EntityFlag.BABY, true);
|
||||
}
|
||||
}
|
||||
if (entityMetadata.getId() == 17) {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
metadata.getFlags().setFlag(EntityFlag.CHARGING, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
metadata.getFlags().setFlag(EntityFlag.DANCING, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,8 @@
|
||||
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.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
||||
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.EntityFlag;
|
||||
import org.geysermc.connector.entity.living.GolemEntity;
|
||||
@ -46,16 +44,17 @@ public class ShulkerEntity extends GolemEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
BlockFace blockFace = (BlockFace) entityMetadata.getValue();
|
||||
metadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) blockFace.ordinal());
|
||||
}
|
||||
if (entityMetadata.getId() == 16) {
|
||||
Position position = (Position) entityMetadata.getValue();
|
||||
if (position != null) {
|
||||
metadata.put(EntityData.SHULKER_ATTACH_POS, Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
||||
}
|
||||
}
|
||||
//TODO - this was removed on Java Edition, but does Bedrock Edition still need it??
|
||||
// if (entityMetadata.getId() == 16) {
|
||||
// Position position = (Position) entityMetadata.getValue();
|
||||
// if (position != null) {
|
||||
// metadata.put(EntityData.SHULKER_ATTACH_POS, Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
||||
// }
|
||||
// }
|
||||
|
||||
if (entityMetadata.getId() == 17) {
|
||||
int height = (byte) entityMetadata.getValue();
|
||||
|
@ -39,7 +39,7 @@ public class SpiderEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.WALL_CLIMBING, (xd & 0x01) == 0x01);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class VexEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
// 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
|
||||
|
@ -44,7 +44,7 @@ public class WitherEntity extends MonsterEntity {
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
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());
|
||||
if (entity == null && session.getPlayerEntity().getEntityId() == (int) entityMetadata.getValue()) {
|
||||
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);
|
||||
} else if (entityMetadata.getId() == 16) {
|
||||
metadata.put(EntityData.WITHER_TARGET_2, targetID);
|
||||
} else if (entityMetadata.getId() == 17) {
|
||||
metadata.put(EntityData.WITHER_TARGET_3, targetID);
|
||||
metadata.put(EntityData.WITHER_TARGET_2, targetID);
|
||||
} 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());
|
||||
|
||||
// Show the shield for the first few seconds of spawning (like Java)
|
||||
|
@ -40,7 +40,7 @@ public class ZoglinEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
||||
if (isBaby) {
|
||||
metadata.put(EntityData.SCALE, .55f);
|
||||
|
@ -40,7 +40,7 @@ public class ZombieEntity extends MonsterEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
||||
if (isBaby) {
|
||||
metadata.put(EntityData.SCALE, .55f);
|
||||
|
@ -42,11 +42,11 @@ public class ZombieVillagerEntity extends ZombieEntity {
|
||||
|
||||
@Override
|
||||
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.SHAKING, (boolean) entityMetadata.getValue());
|
||||
}
|
||||
if (entityMetadata.getId() == 19) {
|
||||
if (entityMetadata.getId() == 20) {
|
||||
VillagerData villagerData = (VillagerData) entityMetadata.getValue();
|
||||
// Region - only one used on Bedrock
|
||||
metadata.put(EntityData.MARK_VARIANT, VillagerEntity.VILLAGER_REGIONS.get(villagerData.getType()));
|
||||
|
@ -45,7 +45,7 @@ public class SpellcasterIllagerEntity extends AbstractIllagerEntity {
|
||||
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
int spellType = (int) (byte) entityMetadata.getValue();
|
||||
// Summon vex, attack, or wololo
|
||||
metadata.getFlags().setFlag(EntityFlag.CASTING, spellType == 1 || spellType == 2 || spellType == 3);
|
||||
|
@ -40,7 +40,7 @@ public class VindicatorEntity extends AbstractIllagerEntity {
|
||||
@Override
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
// Allow the axe to be shown if necessary
|
||||
if (entityMetadata.getId() == 14) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.ANGRY, (xd & 4) == 4);
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
}
|
||||
|
||||
// Extra hearts - is not metadata but an attribute on Bedrock
|
||||
if (entityMetadata.getId() == 14) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||
attributesPacket.setRuntimeEntityId(geyserId);
|
||||
List<AttributeData> attributes = new ArrayList<>();
|
||||
@ -283,7 +283,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
session.sendUpstreamPacket(attributesPacket);
|
||||
}
|
||||
|
||||
if (entityMetadata.getId() == 16) {
|
||||
if (entityMetadata.getId() == 17) {
|
||||
// OptionalPack usage for toggling skin bits
|
||||
// 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
|
||||
@ -292,10 +292,10 @@ public class PlayerEntity extends LivingEntity {
|
||||
}
|
||||
|
||||
// Parrot occupying shoulder
|
||||
if (entityMetadata.getId() == 18 || entityMetadata.getId() == 19) {
|
||||
if (entityMetadata.getId() == 19 || entityMetadata.getId() == 20) {
|
||||
CompoundTag tag = (CompoundTag) entityMetadata.getValue();
|
||||
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
|
||||
return;
|
||||
}
|
||||
@ -321,10 +321,10 @@ public class PlayerEntity extends LivingEntity {
|
||||
rightParrot = parrot;
|
||||
}
|
||||
} else {
|
||||
Entity parrot = (entityMetadata.getId() == 18 ? leftParrot : rightParrot);
|
||||
Entity parrot = (entityMetadata.getId() == 19 ? leftParrot : rightParrot);
|
||||
if (parrot != null) {
|
||||
parrot.despawnEntity(session);
|
||||
if (entityMetadata.getId() == 18) {
|
||||
if (entityMetadata.getId() == 19) {
|
||||
leftParrot = null;
|
||||
} else {
|
||||
rightParrot = null;
|
||||
|
@ -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 it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||
import org.geysermc.connector.utils.MathUtils;
|
||||
|
||||
public class ChunkCache {
|
||||
private static final int MINIMUM_WORLD_HEIGHT = 0;
|
||||
|
||||
private final boolean cache;
|
||||
|
||||
private final Long2ObjectMap<Column> chunks;
|
||||
|
||||
@Setter
|
||||
private int minY;
|
||||
|
||||
public ChunkCache(GeyserSession session) {
|
||||
if (session.getConnector().getWorldManager().hasOwnChunkCache()) {
|
||||
this.cache = false; // To prevent Spigot from initializing
|
||||
@ -87,7 +88,7 @@ public class ChunkCache {
|
||||
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
|
||||
return;
|
||||
}
|
||||
@ -108,7 +109,7 @@ public class ChunkCache {
|
||||
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
|
||||
return BlockTranslator.JAVA_AIR_ID;
|
||||
}
|
||||
|
@ -39,24 +39,51 @@ import java.util.Map;
|
||||
*/
|
||||
public class TagCache {
|
||||
/* 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 */
|
||||
private IntList flowers = IntLists.emptyList();
|
||||
private IntList piglinLoved = IntLists.emptyList();
|
||||
private IntList flowers;
|
||||
private IntList foxFood;
|
||||
private IntList piglinLoved;
|
||||
|
||||
public TagCache() {
|
||||
// Ensure all lists are non-null
|
||||
clear();
|
||||
}
|
||||
|
||||
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"));
|
||||
|
||||
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.foxFood = IntList.of(itemTags.get("minecraft:fox_food"));
|
||||
this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved"));
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.leaves = 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.foxFood = IntLists.emptyList();
|
||||
this.piglinLoved = IntLists.emptyList();
|
||||
}
|
||||
|
||||
@ -64,11 +91,32 @@ public class TagCache {
|
||||
return flowers.contains(itemEntry.getJavaId());
|
||||
}
|
||||
|
||||
public boolean isFoxFood(ItemEntry itemEntry) {
|
||||
return foxFood.contains(itemEntry.getJavaId());
|
||||
}
|
||||
|
||||
public boolean shouldPiglinAdmire(ItemEntry itemEntry) {
|
||||
return piglinLoved.contains(itemEntry.getJavaId());
|
||||
}
|
||||
|
||||
public boolean isWool(BlockMapping blockMapping) {
|
||||
return wool.contains(blockMapping.getJavaBlockId());
|
||||
public boolean isAxeEffective(BlockMapping blockMapping) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
@ -25,8 +25,6 @@
|
||||
|
||||
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.setting.Difficulty;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
||||
@ -53,45 +51,12 @@ public class GeyserWorldManager extends WorldManager {
|
||||
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
|
||||
public boolean hasOwnChunkCache() {
|
||||
// This implementation can only fetch data from the session chunk cache
|
||||
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
|
||||
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.
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
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.player.GameMode;
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
@ -97,16 +85,6 @@ public abstract class WorldManager {
|
||||
*/
|
||||
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>
|
||||
*
|
||||
|
@ -143,12 +143,7 @@ public abstract class BlockTranslator {
|
||||
builder.canBreakWithHand(false);
|
||||
}
|
||||
|
||||
JsonNode toolTypeNode = entry.getValue().get("tool_type");
|
||||
if (toolTypeNode != null) {
|
||||
builder.toolType(toolTypeNode.textValue());
|
||||
} else {
|
||||
builder.toolType("");
|
||||
}
|
||||
builder.toolType(""); //TODO
|
||||
|
||||
JsonNode collisionIndexNode = entry.getValue().get("collision_index");
|
||||
if (hardnessNode != null) {
|
||||
|
@ -41,16 +41,28 @@ public class BlockUtils {
|
||||
*/
|
||||
public static final Position POSITION_ZERO = new Position(0, 0, 0);
|
||||
|
||||
private static boolean correctTool(String blockToolType, String itemToolType) {
|
||||
return (blockToolType.equals("sword") && itemToolType.equals("sword")) ||
|
||||
(blockToolType.equals("shovel") && itemToolType.equals("shovel")) ||
|
||||
(blockToolType.equals("pickaxe") && itemToolType.equals("pickaxe")) ||
|
||||
(blockToolType.equals("axe") && itemToolType.equals("axe")) ||
|
||||
(blockToolType.equals("shears") && itemToolType.equals("shears"));
|
||||
private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
|
||||
switch (itemToolType) {
|
||||
case "axe":
|
||||
return session.getTagCache().isAxeEffective(blockMapping);
|
||||
case "hoe":
|
||||
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) {
|
||||
if (toolType.equals("shears")) return isWoolBlock ? 5.0 : 15.0;
|
||||
private static double toolBreakTimeBonus(String toolType, String toolTier, boolean isShearsEffective) {
|
||||
if (toolType.equals("shears")) return isShearsEffective ? 5.0 : 15.0;
|
||||
if (toolType.equals("")) return 1.0;
|
||||
switch (toolTier) {
|
||||
// https://minecraft.gamepedia.com/Breaking#Speed
|
||||
@ -73,16 +85,14 @@ public class BlockUtils {
|
||||
|
||||
//http://minecraft.gamepedia.com/Breaking
|
||||
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) {
|
||||
double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness;
|
||||
double speed = 1.0 / baseTime;
|
||||
|
||||
if (correctTool) {
|
||||
speed *= toolBreakTimeBonus(toolType, toolTier, isWoolBlock);
|
||||
speed *= toolBreakTimeBonus(toolType, toolTier, isShearsEffective);
|
||||
speed += toolEfficiencyLevel == 0 ? 0 : toolEfficiencyLevel * toolEfficiencyLevel + 1;
|
||||
} else if (toolType.equals("sword")) {
|
||||
speed*= (isCobweb ? 15.0 : 1.5);
|
||||
}
|
||||
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) {
|
||||
boolean isWoolBlock = session.getTagCache().isWool(blockMapping);
|
||||
boolean isCobweb = blockMapping.getJavaBlockId() == BlockTranslator.JAVA_COBWEB_BLOCK_ID;
|
||||
String blockToolType = blockMapping.getToolType();
|
||||
boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice
|
||||
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
|
||||
String toolType = "";
|
||||
String toolTier = "";
|
||||
@ -121,7 +129,7 @@ public class BlockUtils {
|
||||
ToolItemEntry toolItem = (ToolItemEntry) item;
|
||||
toolType = toolItem.getToolType();
|
||||
toolTier = toolItem.getToolTier();
|
||||
correctTool = correctTool(blockToolType, toolType);
|
||||
correctTool = correctTool(session, blockMapping, toolType);
|
||||
}
|
||||
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency");
|
||||
int hasteLevel = 0;
|
||||
@ -129,8 +137,8 @@ public class BlockUtils {
|
||||
|
||||
if (!isSessionPlayer) {
|
||||
// Another entity is currently mining; we have all the information we know
|
||||
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock,
|
||||
isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false,
|
||||
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective,
|
||||
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false,
|
||||
false, false);
|
||||
}
|
||||
|
||||
@ -144,8 +152,8 @@ public class BlockUtils {
|
||||
|
||||
boolean outOfWaterButNotOnGround = (!isInWater) && (!session.getPlayerEntity().isOnGround());
|
||||
boolean insideWaterNotOnGround = isInWater && !session.getPlayerEntity().isOnGround();
|
||||
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isWoolBlock,
|
||||
isCobweb, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity,
|
||||
return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective,
|
||||
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity,
|
||||
outOfWaterButNotOnGround, insideWaterNotOnGround);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,17 @@ public class ChunkUtils {
|
||||
|
||||
public static ChunkData translateToBedrock(GeyserSession session, Column column) {
|
||||
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
|
||||
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) };
|
||||
}
|
||||
|
||||
sections[sectionY] = new ChunkSection(layers);
|
||||
sections[sectionY + sectionYOffset] = new ChunkSection(layers);
|
||||
}
|
||||
|
||||
CompoundTag[] blockEntities = column.getTileEntities();
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren