Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +01:00
Yeet cache chunks
So many features require this config option, and we don't intend on supporting it being both disabled and enabled.
Dieser Commit ist enthalten in:
Ursprung
7b0099e869
Commit
ebf726ce9e
@ -48,9 +48,4 @@ public final class GeyserSpigotConfiguration extends GeyserJacksonConfiguration
|
|||||||
|
|
||||||
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgate, floodgateDataFolder, geyserDataFolder, plugin.getGeyserLogger());
|
floodgateKeyPath = FloodgateKeyLoader.getKeyPath(this, floodgate, floodgateDataFolder, geyserDataFolder, plugin.getGeyserLogger());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCacheChunks() {
|
|
||||||
return true; // We override this as with Bukkit, we have direct access to the server implementation
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,6 @@ public interface GeyserConfiguration {
|
|||||||
|
|
||||||
boolean isAboveBedrockNetherBuilding();
|
boolean isAboveBedrockNetherBuilding();
|
||||||
|
|
||||||
boolean isCacheChunks();
|
|
||||||
|
|
||||||
boolean isForceResourcePacks();
|
boolean isForceResourcePacks();
|
||||||
|
|
||||||
boolean isXboxAchievementsEnabled();
|
boolean isXboxAchievementsEnabled();
|
||||||
|
@ -111,9 +111,6 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
|||||||
@JsonProperty("default-locale")
|
@JsonProperty("default-locale")
|
||||||
private String defaultLocale = null; // is null by default so system language takes priority
|
private String defaultLocale = null; // is null by default so system language takes priority
|
||||||
|
|
||||||
@JsonProperty("cache-chunks")
|
|
||||||
private boolean cacheChunks = false;
|
|
||||||
|
|
||||||
@JsonProperty("cache-images")
|
@JsonProperty("cache-images")
|
||||||
private int cacheImages = 0;
|
private int cacheImages = 0;
|
||||||
|
|
||||||
|
@ -174,12 +174,9 @@ public class FishingHookEntity extends ThrowableEntity {
|
|||||||
* @return true if this entity is currently in air.
|
* @return true if this entity is currently in air.
|
||||||
*/
|
*/
|
||||||
protected boolean isInAir(GeyserSession session) {
|
protected boolean isInAir(GeyserSession session) {
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
return block == BlockTranslator.JAVA_AIR_ID;
|
return block == BlockTranslator.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getDrag(GeyserSession session) {
|
protected float getDrag(GeyserSession session) {
|
||||||
|
@ -94,11 +94,9 @@ public class LivingEntity extends Entity {
|
|||||||
Position bedPosition = (Position) entityMetadata.getValue();
|
Position bedPosition = (Position) entityMetadata.getValue();
|
||||||
if (bedPosition != null) {
|
if (bedPosition != null) {
|
||||||
metadata.put(EntityData.BED_POSITION, Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ()));
|
metadata.put(EntityData.BED_POSITION, Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ()));
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
int bed = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
|
int bed = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
|
||||||
// Bed has to be updated, or else player is floating in the air
|
// Bed has to be updated, or else player is floating in the air
|
||||||
ChunkUtils.updateBlock(session, bed, bedPosition);
|
ChunkUtils.updateBlock(session, bed, bedPosition);
|
||||||
}
|
|
||||||
// Indicate that the player should enter the sleep cycle
|
// Indicate that the player should enter the sleep cycle
|
||||||
// Has to be a byte or it does not work
|
// Has to be a byte or it does not work
|
||||||
// (Bed position is what actually triggers sleep - "pose" is only optional)
|
// (Bed position is what actually triggers sleep - "pose" is only optional)
|
||||||
|
@ -166,12 +166,9 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||||||
* @return true if this entity is currently in water.
|
* @return true if this entity is currently in water.
|
||||||
*/
|
*/
|
||||||
protected boolean isInWater(GeyserSession session) {
|
protected boolean isInWater(GeyserSession session) {
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
return BlockStateValues.getWaterLevel(block) != -1;
|
return BlockStateValues.getWaterLevel(block) != -1;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity(GeyserSession session) {
|
||||||
|
@ -111,7 +111,7 @@ public class VillagerEntity extends AbstractMerchantEntity {
|
|||||||
float bedPositionSubtractorW = 0;
|
float bedPositionSubtractorW = 0;
|
||||||
float bedPositionSubtractorN = 0;
|
float bedPositionSubtractorN = 0;
|
||||||
Vector3i bedPosition = metadata.getPos(EntityData.BED_POSITION, null);
|
Vector3i bedPosition = metadata.getPos(EntityData.BED_POSITION, null);
|
||||||
if (session.getConnector().getConfig().isCacheChunks() && bedPosition != null) {
|
if (bedPosition != null) {
|
||||||
bedId = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
|
bedId = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
|
||||||
}
|
}
|
||||||
String bedRotationZ = BlockTranslator.getJavaIdBlockMap().inverse().get(bedId);
|
String bedRotationZ = BlockTranslator.getJavaIdBlockMap().inverse().get(bedId);
|
||||||
|
@ -233,12 +233,6 @@ public class GeyserSession implements CommandSender {
|
|||||||
@Setter
|
@Setter
|
||||||
private boolean sprinting;
|
private boolean sprinting;
|
||||||
|
|
||||||
/**
|
|
||||||
* Not updated if cache chunks is enabled.
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
private boolean jumping;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the player is swimming in water.
|
* Whether the player is swimming in water.
|
||||||
* Used to update speed when crawling.
|
* Used to update speed when crawling.
|
||||||
|
@ -42,11 +42,7 @@ public class ChunkCache {
|
|||||||
private int minY;
|
private int minY;
|
||||||
|
|
||||||
public ChunkCache(GeyserSession session) {
|
public ChunkCache(GeyserSession session) {
|
||||||
if (session.getConnector().getWorldManager().hasOwnChunkCache()) {
|
this.cache = !session.getConnector().getWorldManager().hasOwnChunkCache(); // To prevent Spigot from initializing
|
||||||
this.cache = false; // To prevent Spigot from initializing
|
|
||||||
} else {
|
|
||||||
this.cache = session.getConnector().getConfig().isCacheChunks();
|
|
||||||
}
|
|
||||||
chunks = cache ? new Long2ObjectOpenHashMap<>() : null;
|
chunks = cache ? new Long2ObjectOpenHashMap<>() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ import org.geysermc.connector.network.translators.item.ItemRegistry;
|
|||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.utils.BlockUtils;
|
import org.geysermc.connector.utils.BlockUtils;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Translator(packet = PlayerActionPacket.class)
|
@Translator(packet = PlayerActionPacket.class)
|
||||||
public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket> {
|
public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket> {
|
||||||
|
|
||||||
@ -162,7 +160,6 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||||||
// Otherwise handled in BedrockInventoryTransactionTranslator
|
// Otherwise handled in BedrockInventoryTransactionTranslator
|
||||||
break;
|
break;
|
||||||
case START_BREAK:
|
case START_BREAK:
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
// Start the block breaking animation
|
// Start the block breaking animation
|
||||||
if (session.getGameMode() != GameMode.CREATIVE) {
|
if (session.getGameMode() != GameMode.CREATIVE) {
|
||||||
int blockState = session.getConnector().getWorldManager().getBlockAt(session, vector);
|
int blockState = session.getConnector().getWorldManager().getBlockAt(session, vector);
|
||||||
@ -198,7 +195,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ClientPlayerActionPacket startBreakingPacket = new ClientPlayerActionPacket(PlayerAction.START_DIGGING, position, BlockFace.values()[packet.getFace()]);
|
ClientPlayerActionPacket startBreakingPacket = new ClientPlayerActionPacket(PlayerAction.START_DIGGING, position, BlockFace.values()[packet.getFace()]);
|
||||||
session.sendDownstreamPacket(startBreakingPacket);
|
session.sendDownstreamPacket(startBreakingPacket);
|
||||||
break;
|
break;
|
||||||
@ -246,11 +243,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||||||
session.getEntityCache().updateBossBars();
|
session.getEntityCache().updateBossBars();
|
||||||
break;
|
break;
|
||||||
case JUMP:
|
case JUMP:
|
||||||
if (!session.getConnector().getConfig().isCacheChunks()) {
|
// Leaving as a potential placeholder for an event or soul sand fixing
|
||||||
// Save the jumping status for determining teleport status
|
|
||||||
session.setJumping(true);
|
|
||||||
session.getConnector().getGeneralThreadPool().schedule(() -> session.setJumping(false), 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,8 +141,6 @@ public class CollisionManager {
|
|||||||
Vector3d position = Vector3d.from(Double.parseDouble(Float.toString(bedrockPosition.getX())), javaY,
|
Vector3d position = Vector3d.from(Double.parseDouble(Float.toString(bedrockPosition.getX())), javaY,
|
||||||
Double.parseDouble(Float.toString(bedrockPosition.getZ())));
|
Double.parseDouble(Float.toString(bedrockPosition.getZ())));
|
||||||
|
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
// With chunk caching, we can do some proper collision checks
|
|
||||||
updatePlayerBoundingBox(position);
|
updatePlayerBoundingBox(position);
|
||||||
|
|
||||||
// Correct player position
|
// Correct player position
|
||||||
@ -160,14 +158,6 @@ public class CollisionManager {
|
|||||||
// Trim the position to prevent rounding errors that make Java think we are clipping into a block
|
// Trim the position to prevent rounding errors that make Java think we are clipping into a block
|
||||||
position = Vector3d.from(position.getX(), Double.parseDouble(DECIMAL_FORMAT.format(position.getY())), position.getZ());
|
position = Vector3d.from(position.getX(), Double.parseDouble(DECIMAL_FORMAT.format(position.getY())), position.getZ());
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// When chunk caching is off, we have to rely on this
|
|
||||||
// It rounds the Y position up to the nearest 0.5
|
|
||||||
// This snaps players to snap to the top of stairs and slabs like on Java Edition
|
|
||||||
// However, it causes issues such as the player floating on carpets
|
|
||||||
if (onGround) javaY = Math.ceil(javaY * 2) / 2;
|
|
||||||
position = position.up(javaY - position.getY());
|
|
||||||
}
|
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@ -268,10 +258,6 @@ public class CollisionManager {
|
|||||||
* were they not sneaking
|
* were they not sneaking
|
||||||
*/
|
*/
|
||||||
public boolean isUnderSlab() {
|
public boolean isUnderSlab() {
|
||||||
if (!session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
// We can't reliably determine this
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Vector3i position = session.getPlayerEntity().getPosition().toInt();
|
Vector3i position = session.getPlayerEntity().getPosition().toInt();
|
||||||
BlockCollision collision = CollisionTranslator.getCollisionAt(session, position.getX(), position.getY(), position.getZ());
|
BlockCollision collision = CollisionTranslator.getCollisionAt(session, position.getX(), position.getY(), position.getZ());
|
||||||
if (collision != null) {
|
if (collision != null) {
|
||||||
@ -289,8 +275,7 @@ public class CollisionManager {
|
|||||||
* @return if the player is currently in a water block
|
* @return if the player is currently in a water block
|
||||||
*/
|
*/
|
||||||
public boolean isPlayerInWater() {
|
public boolean isPlayerInWater() {
|
||||||
return session.getConnector().getConfig().isCacheChunks()
|
return session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt()) == BlockTranslator.JAVA_WATER_ID;
|
||||||
&& session.getConnector().getWorldManager().getBlockAt(session, session.getPlayerEntity().getPosition().toInt()) == BlockTranslator.JAVA_WATER_ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,11 +48,6 @@ public class CollisionTranslator {
|
|||||||
private static final Int2ObjectMap<BlockCollision> COLLISION_MAP = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<BlockCollision> COLLISION_MAP = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// If chunk caching is off then don't initialize
|
|
||||||
if (!GeyserConnector.getInstance().getConfig().isCacheChunks()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Class<?>> collisionTypes = new ArrayList<>();
|
List<Class<?>> collisionTypes = new ArrayList<>();
|
||||||
|
|
||||||
Map<Class<?>, CollisionRemapper> annotationMap = new HashMap<>();
|
Map<Class<?>, CollisionRemapper> annotationMap = new HashMap<>();
|
||||||
|
@ -54,15 +54,6 @@ import java.util.Collections;
|
|||||||
public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator {
|
public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||||
public BeaconInventoryTranslator() {
|
public BeaconInventoryTranslator() {
|
||||||
super(1, new BlockInventoryHolder("minecraft:beacon", ContainerType.BEACON) {
|
super(1, new BlockInventoryHolder("minecraft:beacon", ContainerType.BEACON) {
|
||||||
@Override
|
|
||||||
public void prepareInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
|
|
||||||
if (!session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
// Beacons cannot work without knowing their physical location
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
super.prepareInventory(translator, session, inventory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean checkInteractionPosition(GeyserSession session) {
|
protected boolean checkInteractionPosition(GeyserSession session) {
|
||||||
// Since we can't fall back to a virtual inventory, let's make opening one easier
|
// Since we can't fall back to a virtual inventory, let's make opening one easier
|
||||||
@ -71,7 +62,7 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
|
public void openInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
|
||||||
if (!session.getConnector().getConfig().isCacheChunks() || !((BeaconContainer) inventory).isUsingRealBlock()) {
|
if (!((BeaconContainer) inventory).isUsingRealBlock()) {
|
||||||
InventoryUtils.closeInventory(session, inventory.getId(), false);
|
InventoryUtils.closeInventory(session, inventory.getId(), false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,10 +64,8 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
|
|||||||
passenger = session.getPlayerEntity();
|
passenger = session.getPlayerEntity();
|
||||||
session.setRidingVehicleEntity(entity);
|
session.setRidingVehicleEntity(entity);
|
||||||
// We need to confirm teleports before entering a vehicle, or else we will likely exit right out
|
// We need to confirm teleports before entering a vehicle, or else we will likely exit right out
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
session.confirmTeleport(passenger.getPosition().sub(0, EntityType.PLAYER.getOffset(), 0).toDouble());
|
session.confirmTeleport(passenger.getPosition().sub(0, EntityType.PLAYER.getOffset(), 0).toDouble());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Passenger hasn't loaded in (likely since we're waiting for a skin response)
|
// Passenger hasn't loaded in (likely since we're waiting for a skin response)
|
||||||
// and entity link needs to be set later
|
// and entity link needs to be set later
|
||||||
if (passenger == null && passengerId != 0) {
|
if (passenger == null && passengerId != 0) {
|
||||||
|
@ -25,21 +25,15 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.network.translators.java.entity.player;
|
package org.geysermc.connector.network.translators.java.entity.player;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerActionAckPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerActionAckPacket;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||||
import org.geysermc.connector.inventory.GeyserItemStack;
|
|
||||||
import org.geysermc.connector.inventory.PlayerInventory;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
import org.geysermc.connector.network.translators.Translator;
|
||||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.utils.BlockUtils;
|
|
||||||
import org.geysermc.connector.utils.ChunkUtils;
|
import org.geysermc.connector.utils.ChunkUtils;
|
||||||
|
|
||||||
@Translator(packet = ServerPlayerActionAckPacket.class)
|
@Translator(packet = ServerPlayerActionAckPacket.class)
|
||||||
@ -56,47 +50,5 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayer
|
|||||||
session.setBreakingBlock(BlockTranslator.JAVA_AIR_ID);
|
session.setBreakingBlock(BlockTranslator.JAVA_AIR_ID);
|
||||||
session.sendUpstreamPacket(stopBreak);
|
session.sendUpstreamPacket(stopBreak);
|
||||||
}
|
}
|
||||||
if (!session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
LevelEventPacket levelEvent = new LevelEventPacket();
|
|
||||||
switch (packet.getAction()) {
|
|
||||||
case START_DIGGING:
|
|
||||||
if (session.getGameMode() == GameMode.CREATIVE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
levelEvent.setType(LevelEventType.BLOCK_START_BREAK);
|
|
||||||
levelEvent.setPosition(Vector3f.from(
|
|
||||||
packet.getPosition().getX(),
|
|
||||||
packet.getPosition().getY(),
|
|
||||||
packet.getPosition().getZ()
|
|
||||||
));
|
|
||||||
PlayerInventory inventory = session.getPlayerInventory();
|
|
||||||
GeyserItemStack item = inventory.getItemInHand();
|
|
||||||
ItemEntry itemEntry;
|
|
||||||
CompoundTag nbtData;
|
|
||||||
if (item != null) {
|
|
||||||
itemEntry = item.getItemEntry();
|
|
||||||
nbtData = item.getNbt();
|
|
||||||
} else {
|
|
||||||
itemEntry = null;
|
|
||||||
nbtData = new CompoundTag("");
|
|
||||||
}
|
|
||||||
double breakTime = Math.ceil(BlockUtils.getBreakTime(session, BlockTranslator.getBlockMapping(packet.getNewState()), itemEntry, nbtData, true) * 20);
|
|
||||||
levelEvent.setData((int) (65535 / breakTime));
|
|
||||||
session.setBreakingBlock(packet.getNewState());
|
|
||||||
session.sendUpstreamPacket(levelEvent);
|
|
||||||
break;
|
|
||||||
case CANCEL_DIGGING:
|
|
||||||
levelEvent.setType(LevelEventType.BLOCK_STOP_BREAK);
|
|
||||||
levelEvent.setPosition(Vector3f.from(
|
|
||||||
packet.getPosition().getX(),
|
|
||||||
packet.getPosition().getY(),
|
|
||||||
packet.getPosition().getZ()
|
|
||||||
));
|
|
||||||
levelEvent.setData(0);
|
|
||||||
session.setBreakingBlock(0);
|
|
||||||
session.sendUpstreamPacket(levelEvent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -87,21 +87,6 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
|
|||||||
|
|
||||||
session.setSpawned(true);
|
session.setSpawned(true);
|
||||||
|
|
||||||
// Ignore certain move correction packets for smoother movement
|
|
||||||
// These are never relative
|
|
||||||
// When chunk caching is enabled this isn't needed as we shouldn't get these
|
|
||||||
if (!session.getConnector().getConfig().isCacheChunks() && packet.getRelative().isEmpty()) {
|
|
||||||
double xDis = Math.abs(entity.getPosition().getX() - packet.getX());
|
|
||||||
double yDis = entity.getPosition().getY() - packet.getY();
|
|
||||||
double zDis = Math.abs(entity.getPosition().getZ() - packet.getZ());
|
|
||||||
if (!(xDis > 1.5 || (yDis < 1.45 || yDis > (session.isJumping() ? 4.3 : (session.isSprinting() ? 2.5 : 1.9))) || zDis > 1.5)) {
|
|
||||||
// Fake confirm the teleport but don't send it to the client
|
|
||||||
ClientTeleportConfirmPacket teleportConfirmPacket = new ClientTeleportConfirmPacket(packet.getTeleportId());
|
|
||||||
session.sendDownstreamPacket(teleportConfirmPacket);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If coordinates are relative, then add to the existing coordinate
|
// If coordinates are relative, then add to the existing coordinate
|
||||||
double newX = packet.getX() +
|
double newX = packet.getX() +
|
||||||
(packet.getRelative().contains(PositionElement.X) ? entity.getPosition().getX() : 0);
|
(packet.getRelative().contains(PositionElement.X) ? entity.getPosition().getX() : 0);
|
||||||
|
@ -45,8 +45,7 @@ public class JavaBlockChangeTranslator extends PacketTranslator<ServerBlockChang
|
|||||||
public void translate(ServerBlockChangePacket packet, GeyserSession session) {
|
public void translate(ServerBlockChangePacket packet, GeyserSession session) {
|
||||||
Position pos = packet.getRecord().getPosition();
|
Position pos = packet.getRecord().getPosition();
|
||||||
boolean updatePlacement = session.getConnector().getPlatformType() != PlatformType.SPIGOT && // Spigot simply listens for the block place event
|
boolean updatePlacement = session.getConnector().getPlatformType() != PlatformType.SPIGOT && // Spigot simply listens for the block place event
|
||||||
!(session.getConnector().getConfig().isCacheChunks() &&
|
session.getConnector().getWorldManager().getBlockAt(session, pos) != packet.getRecord().getBlock();
|
||||||
session.getConnector().getWorldManager().getBlockAt(session, pos) == packet.getRecord().getBlock());
|
|
||||||
ChunkUtils.updateBlock(session, packet.getRecord().getBlock(), pos);
|
ChunkUtils.updateBlock(session, packet.getRecord().getBlock(), pos);
|
||||||
if (updatePlacement) {
|
if (updatePlacement) {
|
||||||
this.checkPlace(session, packet);
|
this.checkPlace(session, packet);
|
||||||
|
@ -31,27 +31,22 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdate
|
|||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
|
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
|
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
import org.geysermc.connector.network.translators.Translator;
|
||||||
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||||
|
import org.geysermc.connector.network.translators.world.block.entity.RequiresBlockState;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.SkullBlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.SkullBlockEntityTranslator;
|
||||||
import org.geysermc.connector.utils.BlockEntityUtils;
|
import org.geysermc.connector.utils.BlockEntityUtils;
|
||||||
import org.geysermc.connector.utils.ChunkUtils;
|
|
||||||
|
|
||||||
@Translator(packet = ServerUpdateTileEntityPacket.class)
|
@Translator(packet = ServerUpdateTileEntityPacket.class)
|
||||||
public class JavaUpdateTileEntityTranslator extends PacketTranslator<ServerUpdateTileEntityPacket> {
|
public class JavaUpdateTileEntityTranslator extends PacketTranslator<ServerUpdateTileEntityPacket> {
|
||||||
private final boolean cacheChunks;
|
|
||||||
|
|
||||||
public JavaUpdateTileEntityTranslator() {
|
|
||||||
cacheChunks = GeyserConnector.getInstance().getConfig().isCacheChunks();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) {
|
public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) {
|
||||||
String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name());
|
String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name());
|
||||||
if (packet.getNbt().isEmpty()) { // Fixes errors in CubeCraft sending empty NBT
|
if (packet.getNbt().isEmpty()) { // Fixes errors in servers sending empty NBT
|
||||||
BlockEntityUtils.updateBlockEntity(session, null, packet.getPosition());
|
BlockEntityUtils.updateBlockEntity(session, null, packet.getPosition());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -59,11 +54,12 @@ public class JavaUpdateTileEntityTranslator extends PacketTranslator<ServerUpdat
|
|||||||
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id);
|
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id);
|
||||||
// The Java block state is used in BlockEntityTranslator.translateTag() to make up for some inconsistencies
|
// The Java block state is used in BlockEntityTranslator.translateTag() to make up for some inconsistencies
|
||||||
// between Java block states and Bedrock block entity data
|
// between Java block states and Bedrock block entity data
|
||||||
int blockState = cacheChunks ?
|
int blockState;
|
||||||
// Cache chunks is enabled; use chunk cache
|
if (translator instanceof RequiresBlockState) {
|
||||||
session.getConnector().getWorldManager().getBlockAt(session, packet.getPosition()) :
|
blockState = session.getConnector().getWorldManager().getBlockAt(session, packet.getPosition());
|
||||||
// Cache chunks is not enabled; use block entity cache
|
} else {
|
||||||
ChunkUtils.CACHED_BLOCK_ENTITIES.removeInt(packet.getPosition());
|
blockState = BlockTranslator.JAVA_AIR_ID;
|
||||||
|
}
|
||||||
BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, packet.getNbt(), blockState), packet.getPosition());
|
BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, packet.getNbt(), blockState), packet.getPosition());
|
||||||
// Check for custom skulls.
|
// Check for custom skulls.
|
||||||
if (SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS && packet.getNbt().contains("SkullOwner")) {
|
if (SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS && packet.getNbt().contains("SkullOwner")) {
|
||||||
|
@ -33,11 +33,6 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
|||||||
|
|
||||||
@BlockEntity(name = "Banner")
|
@BlockEntity(name = "Banner")
|
||||||
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
@Override
|
|
||||||
public boolean isBlock(int blockState) {
|
|
||||||
return BlockStateValues.getBannerColor(blockState) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||||
int bannerColor = BlockStateValues.getBannerColor(blockState);
|
int bannerColor = BlockStateValues.getBannerColor(blockState);
|
||||||
|
@ -31,11 +31,6 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
|||||||
|
|
||||||
@BlockEntity(name = "Bed")
|
@BlockEntity(name = "Bed")
|
||||||
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
@Override
|
|
||||||
public boolean isBlock(int blockState) {
|
|
||||||
return BlockStateValues.getBedColor(blockState) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||||
byte bedcolor = BlockStateValues.getBedColor(blockState);
|
byte bedcolor = BlockStateValues.getBedColor(blockState);
|
||||||
|
@ -32,7 +32,14 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||||||
/**
|
/**
|
||||||
* Implemented only if a block is a block entity in Bedrock and not Java Edition.
|
* Implemented only if a block is a block entity in Bedrock and not Java Edition.
|
||||||
*/
|
*/
|
||||||
public interface BedrockOnlyBlockEntity {
|
public interface BedrockOnlyBlockEntity extends RequiresBlockState {
|
||||||
|
/**
|
||||||
|
* Determines if block is part of class
|
||||||
|
* @param blockState BlockState to be compared
|
||||||
|
* @return true if part of the class
|
||||||
|
*/
|
||||||
|
boolean isBlock(int blockState);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the block on Bedrock Edition.
|
* Update the block on Bedrock Edition.
|
||||||
* @param session GeyserSession.
|
* @param session GeyserSession.
|
||||||
|
@ -47,10 +47,9 @@ import java.util.Map;
|
|||||||
public abstract class BlockEntityTranslator {
|
public abstract class BlockEntityTranslator {
|
||||||
public static final Map<String, BlockEntityTranslator> BLOCK_ENTITY_TRANSLATORS = new HashMap<>();
|
public static final Map<String, BlockEntityTranslator> BLOCK_ENTITY_TRANSLATORS = new HashMap<>();
|
||||||
/**
|
/**
|
||||||
* A list of all block entities that require the Java block state in order to fill out their block entity information.
|
* A list of all block entities that only exist on Bedrock
|
||||||
* This list will be smaller with cache chunks on as we don't need to double-cache data
|
|
||||||
*/
|
*/
|
||||||
public static final ObjectArrayList<RequiresBlockState> REQUIRES_BLOCK_STATE_LIST = new ObjectArrayList<>();
|
public static final ObjectArrayList<BedrockOnlyBlockEntity> BEDROCK_ONLY_BLOCK_ENTITIES = new ObjectArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a list of irregular block entity name translations that can't be fit into the regex
|
* Contains a list of irregular block entity name translations that can't be fit into the regex
|
||||||
@ -84,18 +83,12 @@ public abstract class BlockEntityTranslator {
|
|||||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_entity.failed", clazz.getCanonicalName()));
|
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_entity.failed", clazz.getCanonicalName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean cacheChunks = GeyserConnector.getInstance().getConfig().isCacheChunks();
|
for (Class<?> clazz : ref.getSubTypesOf(BedrockOnlyBlockEntity.class)) {
|
||||||
for (Class<?> clazz : ref.getSubTypesOf(RequiresBlockState.class)) {
|
GeyserConnector.getInstance().getLogger().debug("Found Bedrock-only block entity: " + clazz.getCanonicalName());
|
||||||
GeyserConnector.getInstance().getLogger().debug("Found block entity that requires block state: " + clazz.getCanonicalName());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RequiresBlockState requiresBlockState = (RequiresBlockState) clazz.newInstance();
|
BedrockOnlyBlockEntity bedrockOnlyBlockEntity = (BedrockOnlyBlockEntity) clazz.newInstance();
|
||||||
if (cacheChunks && !(requiresBlockState instanceof BedrockOnlyBlockEntity)) {
|
BEDROCK_ONLY_BLOCK_ENTITIES.add(bedrockOnlyBlockEntity);
|
||||||
// Not needed to put this one in the map; cache chunks takes care of that for us
|
|
||||||
GeyserConnector.getInstance().getLogger().debug("Not adding because cache chunks is enabled.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
REQUIRES_BLOCK_STATE_LIST.add(requiresBlockState);
|
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_state.failed", clazz.getCanonicalName()));
|
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_state.failed", clazz.getCanonicalName()));
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,4 @@ public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator imp
|
|||||||
builder.put("LastExecution", (long) 0);
|
builder.put("LastExecution", (long) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBlock(int blockState) {
|
|
||||||
return BlockStateValues.getCommandBlockValues().containsKey(blockState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ import org.geysermc.connector.utils.BlockEntityUtils;
|
|||||||
* Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity
|
* Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity
|
||||||
*/
|
*/
|
||||||
@BlockEntity(name = "Chest")
|
@BlockEntity(name = "Chest")
|
||||||
public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState {
|
public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity {
|
||||||
@Override
|
@Override
|
||||||
public boolean isBlock(int blockState) {
|
public boolean isBlock(int blockState) {
|
||||||
return BlockStateValues.getDoubleChestValues().containsKey(blockState);
|
return BlockStateValues.getDoubleChestValues().containsKey(blockState);
|
||||||
|
@ -33,7 +33,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
import org.geysermc.connector.utils.BlockEntityUtils;
|
import org.geysermc.connector.utils.BlockEntityUtils;
|
||||||
|
|
||||||
public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState {
|
public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity {
|
||||||
/**
|
/**
|
||||||
* @param blockState the Java block state of a potential flower pot block
|
* @param blockState the Java block state of a potential flower pot block
|
||||||
* @return true if the block is a flower pot
|
* @return true if the block is a flower pot
|
||||||
|
@ -30,21 +30,14 @@ import com.nukkitx.math.vector.Vector3i;
|
|||||||
import com.nukkitx.protocol.bedrock.packet.BlockEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.BlockEventPacket;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||||
import org.geysermc.connector.utils.ChunkUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does not implement BlockEntityTranslator because it's only a block entity in Bedrock
|
* Does not implement BlockEntityTranslator because it's only a block entity in Bedrock
|
||||||
*/
|
*/
|
||||||
public class NoteblockBlockEntityTranslator implements RequiresBlockState {
|
public class NoteblockBlockEntityTranslator {
|
||||||
@Override
|
|
||||||
public boolean isBlock(int blockState) {
|
|
||||||
return BlockStateValues.getNoteblockPitch(blockState) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void translate(GeyserSession session, Position position) {
|
public static void translate(GeyserSession session, Position position) {
|
||||||
int blockState = session.getConnector().getConfig().isCacheChunks() ?
|
int blockState = session.getConnector().getWorldManager().getBlockAt(session, position);
|
||||||
session.getConnector().getWorldManager().getBlockAt(session, position) :
|
|
||||||
ChunkUtils.CACHED_BLOCK_ENTITIES.removeInt(position);
|
|
||||||
BlockEventPacket blockEventPacket = new BlockEventPacket();
|
BlockEventPacket blockEventPacket = new BlockEventPacket();
|
||||||
blockEventPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
blockEventPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
||||||
blockEventPacket.setEventType(0);
|
blockEventPacket.setEventType(0);
|
||||||
|
@ -29,12 +29,4 @@ package org.geysermc.connector.network.translators.world.block.entity;
|
|||||||
* Implemented in block entities if their Java block state is required for additional values in Bedrock
|
* Implemented in block entities if their Java block state is required for additional values in Bedrock
|
||||||
*/
|
*/
|
||||||
public interface RequiresBlockState {
|
public interface RequiresBlockState {
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if block is part of class
|
|
||||||
* @param blockState BlockState to be compared
|
|
||||||
* @return true if part of the class
|
|
||||||
*/
|
|
||||||
boolean isBlock(int blockState);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@BlockEntity(name = "ShulkerBox")
|
@BlockEntity(name = "ShulkerBox")
|
||||||
public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator {
|
public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
/**
|
/**
|
||||||
* Also used in {@link org.geysermc.connector.network.translators.inventory.translators.ShulkerInventoryTranslator}
|
* Also used in {@link org.geysermc.connector.network.translators.inventory.translators.ShulkerInventoryTranslator}
|
||||||
* where {@code tag} is passed as null.
|
* where {@code tag} is passed as null.
|
||||||
|
@ -50,11 +50,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
public static boolean ALLOW_CUSTOM_SKULLS;
|
public static boolean ALLOW_CUSTOM_SKULLS;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBlock(int blockState) {
|
|
||||||
return BlockStateValues.getSkullVariant(blockState) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||||
byte skullVariant = BlockStateValues.getSkullVariant(blockState);
|
byte skullVariant = BlockStateValues.getSkullVariant(blockState);
|
||||||
|
@ -42,8 +42,6 @@ import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
|||||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
@ -55,7 +53,6 @@ import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
|||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.BedrockOnlyBlockEntity;
|
import org.geysermc.connector.network.translators.world.block.entity.BedrockOnlyBlockEntity;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.RequiresBlockState;
|
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.SkullBlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.SkullBlockEntityTranslator;
|
||||||
import org.geysermc.connector.network.translators.world.chunk.BlockStorage;
|
import org.geysermc.connector.network.translators.world.chunk.BlockStorage;
|
||||||
import org.geysermc.connector.network.translators.world.chunk.ChunkSection;
|
import org.geysermc.connector.network.translators.world.chunk.ChunkSection;
|
||||||
@ -70,11 +67,6 @@ import static org.geysermc.connector.network.translators.world.block.BlockTransl
|
|||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class ChunkUtils {
|
public class ChunkUtils {
|
||||||
/**
|
|
||||||
* Temporarily stores positions of BlockState values that are needed for certain block entities actively.
|
|
||||||
* Not used if cache chunks is enabled
|
|
||||||
*/
|
|
||||||
public static final Object2IntMap<Position> CACHED_BLOCK_ENTITIES = new Object2IntOpenHashMap<>();
|
|
||||||
|
|
||||||
private static int indexYZXtoXZY(int yzx) {
|
private static int indexYZXtoXZY(int yzx) {
|
||||||
return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8);
|
return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8);
|
||||||
@ -364,20 +356,12 @@ public class ChunkUtils {
|
|||||||
return newLecternHasBook;
|
return newLecternHasBook;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Since Java stores bed colors/skull information as part of the namespaced ID and Bedrock stores it as a tag
|
// Iterates through all Bedrock-only block entity translators and determines if a manual block entity packet
|
||||||
// This is the only place I could find that interacts with the Java block state and block updates
|
// needs to be sent
|
||||||
// Iterates through all block entity translators and determines if the block state needs to be saved
|
for (BedrockOnlyBlockEntity bedrockOnlyBlockEntity : BlockEntityTranslator.BEDROCK_ONLY_BLOCK_ENTITIES) {
|
||||||
for (RequiresBlockState requiresBlockState : BlockEntityTranslator.REQUIRES_BLOCK_STATE_LIST) {
|
if (bedrockOnlyBlockEntity.isBlock(blockState)) {
|
||||||
if (requiresBlockState.isBlock(blockState)) {
|
|
||||||
// Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks
|
// Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks
|
||||||
if (requiresBlockState instanceof BedrockOnlyBlockEntity) {
|
bedrockOnlyBlockEntity.updateBlock(session, blockState, position);
|
||||||
((BedrockOnlyBlockEntity) requiresBlockState).updateBlock(session, blockState, position);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!session.getConnector().getConfig().isCacheChunks()) {
|
|
||||||
// Blocks aren't saved to a chunk cache; resort to this smaller cache
|
|
||||||
CACHED_BLOCK_ENTITIES.put(new Position(position.getX(), position.getY(), position.getZ()), blockState);
|
|
||||||
}
|
|
||||||
break; //No block will be a part of two classes
|
break; //No block will be a part of two classes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,7 +396,6 @@ public class ChunkUtils {
|
|||||||
@Data
|
@Data
|
||||||
public static final class ChunkData {
|
public static final class ChunkData {
|
||||||
private final ChunkSection[] sections;
|
private final ChunkSection[] sections;
|
||||||
|
|
||||||
private final NbtMap[] blockEntities;
|
private final NbtMap[] blockEntities;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,18 +134,6 @@ emote-offhand-workaround: "disabled"
|
|||||||
# The default locale if we dont have the one the client requested. Uncomment to not use the default system language.
|
# The default locale if we dont have the one the client requested. Uncomment to not use the default system language.
|
||||||
# default-locale: en_us
|
# default-locale: en_us
|
||||||
|
|
||||||
# Configures if chunk caching should be enabled or not. This keeps an individual
|
|
||||||
# record of each block the client loads in. This feature does allow for a few things
|
|
||||||
# such as more accurate movement that causes less problems with anticheat (meaning
|
|
||||||
# you're less likely to be banned) and allows block break animations to show up in
|
|
||||||
# creative mode (and other features). Although this increases RAM usage, it likely
|
|
||||||
# won't have much of an effect for the vast majority of people. However, if you're
|
|
||||||
# running out of RAM or are in a RAM-sensitive environment, you may want to disable
|
|
||||||
# this. When using the Spigot version of Geyser, support for features or
|
|
||||||
# implementations this allows is automatically enabled without the additional caching
|
|
||||||
# as Geyser has direct access to the server itself.
|
|
||||||
cache-chunks: true
|
|
||||||
|
|
||||||
# Specify how many days images will be cached to disk to save downloading them from the internet.
|
# Specify how many days images will be cached to disk to save downloading them from the internet.
|
||||||
# A value of 0 is disabled. (Default: 0)
|
# A value of 0 is disabled. (Default: 0)
|
||||||
cache-images: 0
|
cache-images: 0
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren