3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-26 16:12:46 +01:00

Some minor fixes, fix own block breaking progress not showing on the player's end

Dieser Commit ist enthalten in:
onebeastchris 2024-12-08 04:18:07 +08:00
Ursprung a2184e4fae
Commit a41d705c42
11 geänderte Dateien mit 79 neuen und 71 gelöschten Zeilen

Datei anzeigen

@ -685,13 +685,13 @@ public final class EntityDefinitions {
.addTranslator(MetadataType.BOOLEAN, CreakingEntity::setIsTearingDown)
.addTranslator(MetadataType.OPTIONAL_POSITION, CreakingEntity::setHomePos)
.properties(new GeyserEntityProperties.Builder()
.addEnum("minecraft:creaking_state",
.addEnum(CreakingEntity.CREAKING_STATE,
"neutral",
"hostile_observed",
"hostile_unobserved",
"twitching",
"crumbling")
.addInt("minecraft:creaking_swaying_ticks", 0, 6)
.addInt(CreakingEntity.CREAKING_SWAYING_TICKS, 0, 6)
.build())
.build();
CREEPER = EntityDefinition.inherited(CreeperEntity::new, mobEntityBase)

Datei anzeigen

@ -38,8 +38,6 @@ import org.geysermc.geyser.item.enchantment.EnchantmentComponent;
import org.geysermc.geyser.item.type.DyeItem;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
import org.geysermc.geyser.session.cache.tags.GeyserHolderSet;
import org.geysermc.geyser.session.cache.tags.ItemTag;
import org.geysermc.geyser.session.cache.tags.Tag;
import org.geysermc.geyser.util.InteractionResult;
@ -62,7 +60,7 @@ import java.util.UUID;
public class WolfEntity extends TameableEntity {
private byte collarColor = 14; // Red - default
private GeyserHolderSet<Item> repairableItems = null;
private HolderSet repairableItems = null;
private boolean isCurseOfBinding = false;
public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
@ -130,8 +128,7 @@ public class WolfEntity extends TameableEntity {
public void setBody(ItemStack stack) {
super.setBody(stack);
isCurseOfBinding = ItemUtils.hasEffect(session, stack, EnchantmentComponent.PREVENT_ARMOR_CHANGE);
HolderSet set = GeyserItemStack.from(stack).getComponent(DataComponentType.REPAIRABLE);
repairableItems = GeyserHolderSet.convertHolderSet(JavaRegistries.ITEM, set);
repairableItems = GeyserItemStack.from(stack).getComponent(DataComponentType.REPAIRABLE);
}
@Override
@ -166,7 +163,7 @@ public class WolfEntity extends TameableEntity {
return InteractiveTag.REMOVE_WOLF_ARMOR;
}
if (getFlag(EntityFlag.SITTING) &&
session.getTagCache().is(repairableItems, itemInHand.asItem()) &&
session.getTagCache().isItem(repairableItems, itemInHand.asItem()) &&
this.body.isValid() && this.body.getTag() != null &&
this.body.getTag().getInt("Damage") > 0) {
return InteractiveTag.REPAIR_WOLF_ARMOR;

Datei anzeigen

@ -41,10 +41,21 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataTyp
import java.util.Optional;
import java.util.UUID;
/*
* Relevant bits:
* - LevelSoundEvent2Packet(sound=SPAWN, position=(233.5, 112.295, 4717.5), extraData=-1, identifier=minecraft:creaking, babySound=false, relativeVolumeDisabled=false)
* - [11:29:34:768] [CLIENT BOUND] - LevelSoundEvent2Packet(sound=CREAKING_HEART_SPAWN, position=(233.0, 110.0, 4717.0), extraData=-1, identifier=minecraft:creaking, babySound=false, relativeVolumeDisabled=false)
* - [11:29:34:768] [CLIENT BOUND] - LevelSoundEvent2Packet(sound=CREAKING_HEART_SPAWN, position=(235.0, 113.0, 4722.0), extraData=13734, identifier=, babySound=false, relativeVolumeDisabled=false)
* - [11:29:34:768] [CLIENT BOUND] - LevelEventPacket(type=PARTICLE_MOB_BLOCK_SPAWN, position=(233.0, 110.0, 4717.0), data=769)
*
*/
public class CreakingEntity extends MonsterEntity {
private Vector3i homePosition;
public static final String CREAKING_STATE = "minecraft:creaking_state";
public static final String CREAKING_SWAYING_TICKS = "minecraft:creaking_swaying_ticks";
public CreakingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
}
@ -58,7 +69,7 @@ public class CreakingEntity extends MonsterEntity {
@Override
public void addAdditionalSpawnData(AddEntityPacket addEntityPacket) {
propertyManager.add("minecraft:creaking_state", "neutral");
propertyManager.add(CREAKING_STATE, "neutral");
propertyManager.add("minecraft:creaking_swaying_ticks", 0);
propertyManager.applyIntProperties(addEntityPacket.getProperties().getIntProperties());
}
@ -68,11 +79,11 @@ public class CreakingEntity extends MonsterEntity {
setFlag(EntityFlag.BODY_ROTATION_BLOCKED, false);
// unfreeze sound? SoundEvent.UNFREEZE
propertyManager.add("minecraft:creaking_state", "hostile_unobserved");
propertyManager.add(CREAKING_STATE, "hostile_unobserved");
updateBedrockEntityProperties();
} else {
setFlag(EntityFlag.BODY_ROTATION_BLOCKED, true);
propertyManager.add("minecraft:creaking_state", "hostile_observed");
propertyManager.add(CREAKING_STATE, "hostile_observed");
updateBedrockEntityProperties();
}
@ -92,7 +103,7 @@ public class CreakingEntity extends MonsterEntity {
// setFlag(EntityFlag.HIDDEN_WHEN_INVISIBLE, true);
// setFlag(EntityFlag.BODY_ROTATION_BLOCKED, true);
} else {
propertyManager.add("minecraft:creaking_state", "neutral");
propertyManager.add(CREAKING_STATE, "neutral");
}
GeyserImpl.getInstance().getLogger().warning("set active; " + booleanEntityMetadata.toString());
}
@ -100,7 +111,7 @@ public class CreakingEntity extends MonsterEntity {
public void setIsTearingDown(EntityMetadata<Boolean,? extends MetadataType<Boolean>> booleanEntityMetadata) {
GeyserImpl.getInstance().getLogger().warning("set isTearingDown; " + booleanEntityMetadata.toString());
if (booleanEntityMetadata.getValue()) {
propertyManager.add("minecraft:creaking_state", "crumbling");
propertyManager.add(CREAKING_STATE, "crumbling");
updateBedrockEntityProperties();
// LevelEventPacket levelEventPacket = new LevelEventPacket();
// levelEventPacket.setType(ParticleType.CREAKING_CRUMBLE);

Datei anzeigen

@ -40,10 +40,7 @@ import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.enchantment.Enchantment;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
import org.geysermc.geyser.session.cache.tags.GeyserHolderSet;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
@ -403,8 +400,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
return false;
}
GeyserHolderSet<Item> set = GeyserHolderSet.convertHolderSet(JavaRegistries.ITEM, repairable);
return session.getTagCache().is(set, material.asItem());
return session.getTagCache().isItem(repairable, material.asItem());
}
private boolean isRenaming(GeyserSession session, AnvilContainer anvilContainer, boolean bedrock) {

Datei anzeigen

@ -28,16 +28,19 @@ package org.geysermc.geyser.session.cache;
import it.unimi.dsi.fastutil.ints.IntArrays;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserLogger;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
import org.geysermc.geyser.session.cache.tags.GeyserHolderSet;
import org.geysermc.geyser.session.cache.tags.Tag;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
import javax.annotation.ParametersAreNonnullByDefault;
@ -127,6 +130,34 @@ public final class TagCache {
return contains(holderSet.resolveRaw(this), holderSet.getRegistry().toNetworkId(session, object));
}
/**
* Accessible via the {@link #isItem(HolderSet, Item)} method.
* @return true if the specified network ID is in the given {@link HolderSet} set.
*/
private <T> boolean is(@Nullable HolderSet holderSet, @NonNull JavaRegistryKey<T> registry, int id) {
if (holderSet == null) {
return false;
}
int[] entries = holderSet.resolve(key -> {
if (key.value().startsWith("#")) {
key = Key.key(key.namespace(), key.value().substring(1));
}
return getRaw(new Tag<>(registry, key));
});
return contains(entries, id);
}
public boolean isItem(@Nullable HolderSet holderSet, @NonNull Item item) {
return is(holderSet, JavaRegistries.ITEM, item.javaId());
}
public boolean isBlock(@Nullable HolderSet holderSet, @NonNull Block block) {
return is(holderSet, JavaRegistries.BLOCK, block.javaId());
}
public <T> List<T> get(Tag<T> tag) {
return mapRawArray(session, getRaw(tag), tag.registry());
}

Datei anzeigen

@ -33,7 +33,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.TagCache;
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import java.util.List;
import java.util.Objects;
@ -88,27 +87,6 @@ public final class GeyserHolderSet<T> {
return tagCache.getRaw(Objects.requireNonNull(tag, "HolderSet must have a tag if it doesn't have a list of IDs"));
}
/**
* Reads a MCPL {@link HolderSet} and turns it into a GeyserHolderSet.
* @param registry the registry the HolderSet contains IDs from.
* @param holderSet the HolderSet as the MCPL HolderSet object
*/
public static <T> GeyserHolderSet<T> convertHolderSet(@NonNull JavaRegistryKey<T> registry, @Nullable HolderSet holderSet) {
if (holderSet == null) {
return new GeyserHolderSet<>(registry, IntArrays.EMPTY_ARRAY);
}
if (holderSet.getHolders() != null) {
return new GeyserHolderSet<>(registry, holderSet.getHolders());
}
if (holderSet.getLocation() != null) {
return new GeyserHolderSet<>(registry, new Tag<>(registry, holderSet.getLocation()));
}
throw new IllegalStateException("HolderSet must have a tag or a list of IDs! " + holderSet);
}
/**
* Reads a HolderSet from an object from NBT.
*

Datei anzeigen

@ -89,7 +89,7 @@ final class BedrockBlockActions {
LevelEventPacket startBreak = new LevelEventPacket();
startBreak.setType(LevelEvent.BLOCK_START_BREAK);
startBreak.setPosition(vector.toFloat());
double breakTime = BlockUtils.getSessionBreakTime(session, BlockState.of(blockState).block()) * 20; // TODO afdaöwelfunöwoaenf
double breakTime = BlockUtils.getSessionBreakTimeTicks(session, BlockState.of(blockState).block());
// If the block is custom or the breaking item is custom, we must keep track of break time ourselves
GeyserItemStack item = session.getPlayerInventory().getItemInHand();
@ -137,7 +137,7 @@ final class BedrockBlockActions {
Direction direction = Direction.VALUES[blockFace];
spawnBlockBreakParticles(session, direction, vector, breakingBlockState);
double breakTime = BlockUtils.getSessionBreakTime(session, breakingBlockState.block()) * 20;
double breakTime = BlockUtils.getSessionBreakTimeTicks(session, breakingBlockState.block());
// If the block is custom, we must keep track of when it should break ourselves
long blockBreakStartTime = session.getBlockBreakStartTime();
if (blockBreakStartTime != 0) {

Datei anzeigen

@ -40,7 +40,7 @@ import java.util.Set;
@Translator(packet = ClientboundSelectKnownPacks.class)
public class JavaSelectKnownPacksTranslator extends PacketTranslator<ClientboundSelectKnownPacks> {
// todo: dump from client?
private static final Set<String> KNOWN_PACK_IDS = Set.of("core", "winter_drop", "trade_rebalance", "redstone_experiments", "minecart_improvements");
private static final Set<String> KNOWN_PACK_IDS = Set.of("core", "trade_rebalance", "redstone_experiments", "minecart_improvements");
@Override
public void translate(GeyserSession session, ClientboundSelectKnownPacks packet) {

Datei anzeigen

@ -37,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet;
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.EvokerFangsEntity;
@ -294,6 +295,8 @@ public class JavaEntityEventTranslator extends PacketTranslator<ClientboundEntit
creakingEntity.createParticleBeam();
}
break;
default:
GeyserImpl.getInstance().getLogger().debug("unhandled entity event: " + packet);
}
if (entityEventPacket.getType() != null) {

Datei anzeigen

@ -41,7 +41,12 @@ public class JavaBlockDestructionTranslator extends PacketTranslator<Clientbound
@Override
public void translate(GeyserSession session, ClientboundBlockDestructionPacket packet) {
int state = session.getGeyser().getWorldManager().getBlockAt(session, packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ());
int breakTime = (int) (65535 / Math.ceil(BlockUtils.getBreakTime(session, BlockState.of(state).block(), ItemMapping.AIR, null, false) * 20));
int breakTime = 12; //(int) (65535 / Math.ceil(BlockUtils.getBreakTime(session, BlockState.of(state).block(), ItemMapping.AIR, null, false)));
// TODO we need to send a "total" time to Bedrock.
// Current plan:
// - start with block destroy time (if applicable)
// - track the time in ticks between stages
// - attempt to "extrapolate" to a value for Bedrock
LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(packet.getPosition().toFloat());
levelEventPacket.setType(LevelEvent.BLOCK_START_BREAK);

Datei anzeigen

@ -25,33 +25,31 @@
package org.geysermc.geyser.util;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.math.vector.Vector3i;
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.EntityEffectCache;
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
import org.geysermc.geyser.session.cache.tags.GeyserHolderSet;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ToolData;
public final class BlockUtils {
public static float getBlockDestroyProgress(GeyserSession session, BlockState blockState, GeyserItemStack itemInHand) {
float destroySpeed = blockState.block().destroyTime();
/**
* Returns the total mining progress added by mining the block in a single tick
* @return the mining progress added by this tick.
*/
public static float getBlockMiningProgressPerTick(GeyserSession session, Block block, GeyserItemStack itemInHand) {
float destroySpeed = block.destroyTime();
if (destroySpeed == -1) {
return 0;
}
int speedMultiplier = hasCorrectTool(session, blockState.block(), itemInHand) ? 30 : 100;
return getPlayerDestroySpeed(session, blockState, itemInHand) / destroySpeed / speedMultiplier;
int speedMultiplier = hasCorrectTool(session, block, itemInHand) ? 30 : 100;
return getPlayerDestroySpeed(session, block, itemInHand) / destroySpeed / speedMultiplier;
}
private static boolean hasCorrectTool(GeyserSession session, Block block, GeyserItemStack stack) {
@ -66,8 +64,7 @@ public final class BlockUtils {
for (ToolData.Rule rule : tool.getRules()) {
if (rule.getCorrectForDrops() != null) {
GeyserHolderSet<Block> set = GeyserHolderSet.convertHolderSet(JavaRegistries.BLOCK, rule.getBlocks());
if (session.getTagCache().is(set, block)) {
if (session.getTagCache().isBlock(rule.getBlocks(), block)) {
return rule.getCorrectForDrops();
}
}
@ -84,8 +81,7 @@ public final class BlockUtils {
for (ToolData.Rule rule : tool.getRules()) {
if (rule.getSpeed() != null) {
GeyserHolderSet<Block> set = GeyserHolderSet.convertHolderSet(JavaRegistries.BLOCK, rule.getBlocks());
if (session.getTagCache().is(set, block)) {
if (session.getTagCache().isBlock(rule.getBlocks(), block)) {
return rule.getSpeed();
}
}
@ -94,8 +90,8 @@ public final class BlockUtils {
return tool.getDefaultMiningSpeed();
}
private static float getPlayerDestroySpeed(GeyserSession session, BlockState blockState, GeyserItemStack itemInHand) {
float destroySpeed = getItemDestroySpeed(session, blockState.block(), itemInHand);
private static float getPlayerDestroySpeed(GeyserSession session, Block block, GeyserItemStack itemInHand) {
float destroySpeed = getItemDestroySpeed(session, block, itemInHand);
EntityEffectCache effectCache = session.getEffectCache();
if (destroySpeed > 1.0F) {
@ -133,17 +129,8 @@ public final class BlockUtils {
return Math.max(cache.getHaste(), cache.getConduitPower());
}
public int getDestroyStage(GeyserSession session) {
return session.getDestroyProgress() > 0F ? (int) session.getDestroyProgress() * 10 : -1;
}
// TODO 1.21.4 this changed probably; no more tiers
public static double getBreakTime(GeyserSession session, Block block, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) {
return 0.0; // TODO 1.21.4
}
public static double getSessionBreakTime(GeyserSession session, Block block) {
return 0.0; // TODO 1.21.4
public static double getSessionBreakTimeTicks(GeyserSession session, Block block) {
return Math.ceil(1 / getBlockMiningProgressPerTick(session, block, session.getPlayerInventory().getItemInHand()));
}
/**