mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
parent
c9e423a593
commit
7d5c4a38f8
3 changed files with 49 additions and 41 deletions
|
@ -50,6 +50,7 @@ public enum GeyserAttributeType {
|
|||
ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f),
|
||||
MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f),
|
||||
SCALE("minecraft:generic.scale", null, 0.0625f, 16f, 1f),
|
||||
BLOCK_INTERACTION_RANGE("minecraft:player.block_interaction_range", null, 0.0f, 64f, 4.5f),
|
||||
|
||||
// Bedrock Attributes
|
||||
ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f),
|
||||
|
|
|
@ -64,6 +64,11 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
*/
|
||||
@Getter
|
||||
protected final Map<GeyserAttributeType, AttributeData> attributes = new Object2ObjectOpenHashMap<>();
|
||||
/**
|
||||
* Java-only attribute
|
||||
*/
|
||||
@Getter
|
||||
private double blockInteractionRange = GeyserAttributeType.BLOCK_INTERACTION_RANGE.getDefaultValue();
|
||||
/**
|
||||
* Used in PlayerInputTranslator for movement checks.
|
||||
*/
|
||||
|
@ -232,6 +237,8 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
protected void updateAttribute(Attribute javaAttribute, List<AttributeData> newAttributes) {
|
||||
if (javaAttribute.getType() == AttributeType.Builtin.GENERIC_ATTACK_SPEED) {
|
||||
session.setAttackSpeed(AttributeUtils.calculateValue(javaAttribute));
|
||||
} else if (javaAttribute.getType() == AttributeType.Builtin.PLAYER_BLOCK_INTERACTION_RANGE) {
|
||||
this.blockInteractionRange = AttributeUtils.calculateValue(javaAttribute);
|
||||
} else {
|
||||
super.updateAttribute(javaAttribute, newAttributes);
|
||||
}
|
||||
|
@ -295,6 +302,7 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
public void resetAttributes() {
|
||||
attributes.clear();
|
||||
maxHealth = GeyserAttributeType.MAX_HEALTH.getDefaultValue();
|
||||
blockInteractionRange = GeyserAttributeType.BLOCK_INTERACTION_RANGE.getDefaultValue();
|
||||
|
||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||
attributesPacket.setRuntimeEntityId(geyserId);
|
||||
|
|
|
@ -70,7 +70,11 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
|||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.*;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.geyser.util.CooldownUtils;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
@ -78,7 +82,11 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractActio
|
|||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.*;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -90,11 +98,6 @@ import java.util.concurrent.TimeUnit;
|
|||
@Translator(packet = InventoryTransactionPacket.class)
|
||||
public class BedrockInventoryTransactionTranslator extends PacketTranslator<InventoryTransactionPacket> {
|
||||
|
||||
private static final float MAXIMUM_BLOCK_PLACING_DISTANCE = 64f;
|
||||
private static final int CREATIVE_EYE_HEIGHT_PLACE_DISTANCE = 49;
|
||||
private static final int SURVIVAL_EYE_HEIGHT_PLACE_DISTANCE = 36;
|
||||
private static final float MAXIMUM_BLOCK_DESTROYING_DISTANCE = 36f;
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, InventoryTransactionPacket packet) {
|
||||
if (packet.getTransactionType() == InventoryTransactionType.NORMAL && packet.getActions().size() == 3) {
|
||||
|
@ -243,17 +246,13 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
return;
|
||||
}
|
||||
|
||||
// CraftBukkit+ check - see https://github.com/PaperMC/Paper/blob/458db6206daae76327a64f4e2a17b67a7e38b426/Spigot-Server-Patches/0532-Move-range-check-for-block-placing-up.patch
|
||||
// As of 1.21, Paper does not have any additional range checks that would inconvenience normal players.
|
||||
// Note that, before these changes, I could replicate on Paper 1.20.4 and iPad 1.21.2 an instance of block ghosting
|
||||
// that we had not previously implemented. Might be some sort of ray tracing that is currently unimplemented.
|
||||
Vector3f playerPosition = session.getPlayerEntity().getPosition();
|
||||
playerPosition = playerPosition.down(EntityDefinitions.PLAYER.offset() - session.getEyeHeight());
|
||||
|
||||
boolean creative = session.getGameMode() == GameMode.CREATIVE;
|
||||
|
||||
float diffX = playerPosition.getX() - packetBlockPosition.getX();
|
||||
float diffY = playerPosition.getY() - packetBlockPosition.getY();
|
||||
float diffZ = playerPosition.getZ() - packetBlockPosition.getZ();
|
||||
if (((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ)) >
|
||||
(creative ? CREATIVE_EYE_HEIGHT_PLACE_DISTANCE : SURVIVAL_EYE_HEIGHT_PLACE_DISTANCE)) {
|
||||
if (!canInteractWithBlock(session, playerPosition, packetBlockPosition)) {
|
||||
restoreCorrectBlock(session, blockPos, packet);
|
||||
return;
|
||||
}
|
||||
|
@ -262,26 +261,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
double clickPositionFullY = (double) packetBlockPosition.getY() + (double) packet.getClickPosition().getY();
|
||||
double clickPositionFullZ = (double) packetBlockPosition.getZ() + (double) packet.getClickPosition().getZ();
|
||||
|
||||
// More recent Paper check - https://github.com/PaperMC/Paper/blob/87e11bf7fdf48ecdf3e1cae383c368b9b61d7df9/patches/server/0470-Move-range-check-for-block-placing-up.patch
|
||||
double clickDiffX = playerPosition.getX() - clickPositionFullX;
|
||||
double clickDiffY = playerPosition.getY() - clickPositionFullY;
|
||||
double clickDiffZ = playerPosition.getZ() - clickPositionFullZ;
|
||||
if (((clickDiffX * clickDiffX) + (clickDiffY * clickDiffY) + (clickDiffZ * clickDiffZ)) >
|
||||
(creative ? CREATIVE_EYE_HEIGHT_PLACE_DISTANCE : SURVIVAL_EYE_HEIGHT_PLACE_DISTANCE)) {
|
||||
restoreCorrectBlock(session, blockPos, packet);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3f blockCenter = Vector3f.from(packetBlockPosition.getX() + 0.5f, packetBlockPosition.getY() + 0.5f, packetBlockPosition.getZ() + 0.5f);
|
||||
// Vanilla check
|
||||
if (!(session.getPlayerEntity().getPosition().sub(0, EntityDefinitions.PLAYER.offset(), 0)
|
||||
.distanceSquared(blockCenter) < MAXIMUM_BLOCK_PLACING_DISTANCE)) {
|
||||
// The client thinks that its blocks have been successfully placed. Restore the server's blocks instead.
|
||||
restoreCorrectBlock(session, blockPos, packet);
|
||||
return;
|
||||
}
|
||||
|
||||
// More recent vanilla check (as of 1.18.2)
|
||||
double clickDistanceX = clickPositionFullX - blockCenter.getX();
|
||||
double clickDistanceY = clickPositionFullY - blockCenter.getY();
|
||||
double clickDistanceZ = clickPositionFullZ - blockCenter.getZ();
|
||||
|
@ -433,14 +414,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
return;
|
||||
}
|
||||
|
||||
// This is working out the distance using 3d Pythagoras and the extra value added to the Y is the sneaking height of a java player.
|
||||
Vector3f playerPosition = session.getPlayerEntity().getPosition();
|
||||
Vector3f floatBlockPosition = packet.getBlockPosition().toFloat();
|
||||
float diffX = playerPosition.getX() - (floatBlockPosition.getX() + 0.5f);
|
||||
float diffY = (playerPosition.getY() - EntityDefinitions.PLAYER.offset()) - (floatBlockPosition.getY() + 0.5f) + 1.5f;
|
||||
float diffZ = playerPosition.getZ() - (floatBlockPosition.getZ() + 0.5f);
|
||||
float distanceSquared = diffX * diffX + diffY * diffY + diffZ * diffZ;
|
||||
if (distanceSquared > MAXIMUM_BLOCK_DESTROYING_DISTANCE) {
|
||||
playerPosition = playerPosition.down(EntityDefinitions.PLAYER.offset() - session.getEyeHeight());
|
||||
|
||||
if (!canInteractWithBlock(session, playerPosition, packet.getBlockPosition())) {
|
||||
restoreCorrectBlock(session, packet.getBlockPosition(), packet);
|
||||
return;
|
||||
}
|
||||
|
@ -550,6 +527,28 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
}
|
||||
}
|
||||
|
||||
private boolean canInteractWithBlock(GeyserSession session, Vector3f playerPosition, Vector3i packetBlockPosition) {
|
||||
// ViaVersion sends this 1.20.5+ attribute also, so older servers will have correct range checks.
|
||||
double blockInteractionRange = session.getPlayerEntity().getBlockInteractionRange();
|
||||
|
||||
// Mojmap Player#canInteractWithBlock
|
||||
double additionalRangeCheck = blockInteractionRange + 1.0d;
|
||||
|
||||
// AABB.<init>(BlockPos)
|
||||
float minX = packetBlockPosition.getX();
|
||||
float minY = packetBlockPosition.getY();
|
||||
float minZ = packetBlockPosition.getZ();
|
||||
float maxX = packetBlockPosition.getX() + 1;
|
||||
float maxY = packetBlockPosition.getY() + 1;
|
||||
float maxZ = packetBlockPosition.getZ() + 1;
|
||||
|
||||
// AABB#distanceToSqr
|
||||
float diffX = Math.max(Math.max(minX - playerPosition.getX(), playerPosition.getX() - maxX), 0);
|
||||
float diffY = Math.max(Math.max(minY - playerPosition.getY(), playerPosition.getY() - maxY), 0);
|
||||
float diffZ = Math.max(Math.max(minZ - playerPosition.getZ(), playerPosition.getZ() - maxZ), 0);
|
||||
return ((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ)) < (additionalRangeCheck * additionalRangeCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the correct block state from the server without updating the chunk cache.
|
||||
*
|
||||
|
@ -696,4 +695,4 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
}, 150, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue