fix: Player#switchEntityType throws an exception

(cherry picked from commit 9fc4137995)
This commit is contained in:
mworzala 2024-01-29 14:53:15 -05:00 committed by Matt Worzala
parent 0bef1b37fc
commit 3a25d0124d
4 changed files with 52 additions and 7 deletions

View File

@ -63,6 +63,7 @@ public class Main {
commandManager.register(new TestCommand2());
commandManager.register(new ConfigCommand());
commandManager.register(new SidebarCommand());
commandManager.register(new SetEntityType());
commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage(Component.text("Unknown command", NamedTextColor.RED)));

View File

@ -0,0 +1,29 @@
package net.minestom.demo.commands;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.minecraft.registry.ArgumentEntityType;
import net.minestom.server.entity.Player;
import org.jetbrains.annotations.NotNull;
public class SetEntityType extends Command {
private final ArgumentEntityType entityTypeArg = ArgumentType.EntityType("type");
public SetEntityType() {
super("setentitytype");
addSyntax(this::execute, entityTypeArg);
}
private void execute(@NotNull CommandSender sender, @NotNull CommandContext context) {
if (!(sender instanceof Player player)) {
return;
}
var entityType = context.get(entityTypeArg);
player.switchEntityType(entityType);
player.sendMessage("set entity type to " + entityType);
}
}

View File

@ -819,6 +819,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
Pose oldPose = getPose();
Pose newPose;
// If they are not a player, do nothing
if (!getEntityType().equals(EntityType.PLAYER)) return;
// Figure out their expected state
var meta = Objects.requireNonNull(getLivingEntityMeta());
if (meta.isFlyingWithElytra()) {
@ -1014,27 +1017,39 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
sendPacket(new UpdateHealthPacket(health, food, foodSaturation));
}
@Override
public @NotNull PlayerMeta getEntityMeta() {
/**
* Gets the entity meta for the player.
*
* <p>Note that this method will throw an exception if the player's entity type has
* been changed with {@link #switchEntityType(EntityType)}. It is wise to check
* {@link #getEntityType()} first.</p>
*/
public @NotNull PlayerMeta getPlayerMeta() {
return (PlayerMeta) super.getEntityMeta();
}
/**
* Gets the player additional hearts.
*
* <p>Note that this function is uncallable if the player has their entity type switched
* with {@link #switchEntityType(EntityType)}.</p>
*
* @return the player additional hearts
*/
public float getAdditionalHearts() {
return getEntityMeta().getAdditionalHearts();
return getPlayerMeta().getAdditionalHearts();
}
/**
* Changes the amount of additional hearts shown.
*
* <p>Note that this function is uncallable if the player has their entity type switched
* with {@link #switchEntityType(EntityType)}.</p>
*
* @param additionalHearts the count of additional hearts
*/
public void setAdditionalHearts(float additionalHearts) {
getEntityMeta().setAdditionalHearts(additionalHearts);
getPlayerMeta().setAdditionalHearts(additionalHearts);
}
/**

View File

@ -4,7 +4,7 @@ import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.item.ItemUpdateStateEvent;
import net.minestom.server.event.player.PlayerCancelDiggingEvent;
@ -145,8 +145,8 @@ public final class PlayerDiggingListener {
}
private static void updateItemState(Player player) {
PlayerMeta meta = player.getEntityMeta();
if (!meta.isHandActive()) return;
LivingEntityMeta meta = player.getLivingEntityMeta();
if (meta == null || !meta.isHandActive()) return;
Player.Hand hand = meta.getActiveHand();
player.refreshEating(null);