9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

Merge pull request #395 from jhqwqmc/dev

改进几个命令
This commit is contained in:
XiaoMoMi
2025-10-03 22:07:46 +08:00
committed by GitHub
13 changed files with 123 additions and 64 deletions

View File

@@ -1,5 +1,8 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature; package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.ImmutableBlockState;
@@ -7,6 +10,7 @@ import net.momirealms.craftengine.core.block.parser.BlockStateParser;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import net.momirealms.craftengine.core.plugin.command.FlagKeys; import net.momirealms.craftengine.core.plugin.command.FlagKeys;
import net.momirealms.craftengine.core.plugin.command.sender.Sender;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command; import org.incendo.cloud.Command;
@@ -38,7 +42,11 @@ public class DebugGetBlockInternalIdCommand extends BukkitCommandFeature<Command
String data = context.get("id"); String data = context.get("id");
ImmutableBlockState state = BlockStateParser.deserialize(data); ImmutableBlockState state = BlockStateParser.deserialize(data);
if (state == null) return; if (state == null) return;
context.sender().sendMessage(BlockStateUtils.getBlockOwnerIdFromState(state.customBlockState().literalObject()).toString()); String id = BlockStateUtils.getBlockOwnerIdFromState(state.customBlockState().literalObject()).toString();
Sender sender = plugin().senderFactory().wrap(context.sender());
sender.sendMessage(Component.text(id)
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
.clickEvent(ClickEvent.suggestCommand(id)));
}); });
} }

View File

@@ -1,13 +1,16 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature; package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import net.momirealms.craftengine.core.plugin.command.sender.Sender;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.incendo.cloud.Command; import org.incendo.cloud.Command;
import org.incendo.cloud.parser.standard.StringParser; import org.incendo.cloud.parser.standard.StringParser;
@@ -20,13 +23,15 @@ public class DebugGetBlockStateRegistryIdCommand extends BukkitCommandFeature<Co
@Override @Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) { public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder return builder
.senderType(Player.class)
.required("state", StringParser.greedyStringParser()) .required("state", StringParser.greedyStringParser())
.handler(context -> { .handler(context -> {
String state = context.get("state"); String state = context.get("state");
BlockData blockData = Bukkit.createBlockData(state); BlockData blockData = Bukkit.createBlockData(state);
int id = BlockStateUtils.blockDataToId(blockData); int id = BlockStateUtils.blockDataToId(blockData);
context.sender().sendMessage(String.valueOf(id)); Sender sender = plugin().senderFactory().wrap(context.sender());
sender.sendMessage(Component.text(id)
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
.clickEvent(ClickEvent.suggestCommand(String.valueOf(id))));
}); });
} }

View File

@@ -1,6 +1,8 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature; package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
@@ -42,13 +44,18 @@ public class DebugTargetBlockCommand extends BukkitCommandFeature<CommandSender>
String bData = block.getBlockData().getAsString(); String bData = block.getBlockData().getAsString();
Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData());
Sender sender = plugin().senderFactory().wrap(context.sender()); Sender sender = plugin().senderFactory().wrap(context.sender());
sender.sendMessage(Component.text(bData)); sender.sendMessage(Component.text(bData)
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
.clickEvent(ClickEvent.suggestCommand(bData)));
int id = BlockStateUtils.blockStateToId(blockState); int id = BlockStateUtils.blockStateToId(blockState);
if (!BlockStateUtils.isVanillaBlock(id)) { if (!BlockStateUtils.isVanillaBlock(id)) {
Object holder = BukkitBlockManager.instance().getMinecraftBlockHolder(id); Object holder = BukkitBlockManager.instance().getMinecraftBlockHolder(id);
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(id); ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(id);
if (immutableBlockState != null) { if (immutableBlockState != null) {
sender.sendMessage(Component.text(immutableBlockState.toString())); String bState = immutableBlockState.toString();
sender.sendMessage(Component.text(bState)
.hoverEvent(Component.text("Copy", NamedTextColor.YELLOW))
.clickEvent(ClickEvent.suggestCommand(bState)));
} }
ImmutableBlockState dataInCache = plugin().worldManager().getWorld(block.getWorld().getUID()).getBlockStateAtIfLoaded(LocationUtils.toBlockPos(block.getLocation())); ImmutableBlockState dataInCache = plugin().worldManager().getWorld(block.getWorld().getUID()).getBlockStateAtIfLoaded(LocationUtils.toBlockPos(block.getLocation()));
sender.sendMessage(Component.text("cache-state: " + (dataInCache != null && !dataInCache.isEmpty()))); sender.sendMessage(Component.text("cache-state: " + (dataInCache != null && !dataInCache.isEmpty())));

View File

@@ -5,6 +5,7 @@ import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.api.CraftEngineItems; import net.momirealms.craftengine.bukkit.api.CraftEngineItems;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.PlayerUtils; import net.momirealms.craftengine.bukkit.util.PlayerUtils;
import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
@@ -61,9 +62,10 @@ public class GetItemCommand extends BukkitCommandFeature<CommandSender> {
itemId = customItem.id(); itemId = customItem.id();
} }
} }
Item<ItemStack> builtItem = customItem.buildItem(BukkitAdaptors.adapt(player)); BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
Item<ItemStack> builtItem = customItem.buildItem(serverPlayer);
if (builtItem != null) { if (builtItem != null) {
PlayerUtils.giveItem(player, amount, builtItem); PlayerUtils.giveItem(serverPlayer, amount, builtItem);
} }
handleFeedback(context, MessageConstants.COMMAND_ITEM_GET_SUCCESS, Component.text(amount), Component.text(itemId.toString())); handleFeedback(context, MessageConstants.COMMAND_ITEM_GET_SUCCESS, Component.text(amount), Component.text(itemId.toString()));
}); });

View File

@@ -5,6 +5,7 @@ import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.api.CraftEngineItems; import net.momirealms.craftengine.bukkit.api.CraftEngineItems;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.PlayerUtils; import net.momirealms.craftengine.bukkit.util.PlayerUtils;
import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
@@ -66,9 +67,10 @@ public class GiveItemCommand extends BukkitCommandFeature<CommandSender> {
} }
Collection<Player> players = selector.values(); Collection<Player> players = selector.values();
for (Player player : players) { for (Player player : players) {
Item<ItemStack> builtItem = customItem.buildItem(BukkitAdaptors.adapt(player)); BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
Item<ItemStack> builtItem = customItem.buildItem(serverPlayer);
if (builtItem != null) { if (builtItem != null) {
PlayerUtils.giveItem(player, amount, builtItem); PlayerUtils.giveItem(serverPlayer, amount, builtItem);
} }
} }
if (players.size() == 1) { if (players.size() == 1) {

View File

@@ -1,17 +1,20 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature; package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.item.ComponentTypes; import net.momirealms.craftengine.bukkit.item.ComponentTypes;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.bukkit.util.PlayerUtils; import net.momirealms.craftengine.bukkit.util.PlayerUtils;
import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.item.ItemKeys;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import net.momirealms.craftengine.core.plugin.command.FlagKeys; import net.momirealms.craftengine.core.plugin.command.FlagKeys;
import net.momirealms.craftengine.core.plugin.locale.MessageConstants; import net.momirealms.craftengine.core.plugin.locale.MessageConstants;
import net.momirealms.craftengine.core.sound.SoundData;
import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
@@ -30,7 +33,6 @@ import org.incendo.cloud.parser.flag.CommandFlag;
import org.incendo.cloud.suggestion.Suggestion; import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.suggestion.SuggestionProvider; import org.incendo.cloud.suggestion.SuggestionProvider;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -51,8 +53,7 @@ public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
return CompletableFuture.completedFuture(plugin().itemManager().cachedTotemSuggestions()); return CompletableFuture.completedFuture(plugin().itemManager().cachedTotemSuggestions());
} }
})) }))
.flag(CommandFlag.builder("sound_event").withComponent(NamespacedKeyParser.namespacedKeyParser()).build()) .flag(CommandFlag.builder("sound").withComponent(NamespacedKeyParser.namespacedKeyParser()).build())
.flag(CommandFlag.builder("sound_location").withComponent(NamespacedKeyParser.namespacedKeyParser()).build())
.handler(context -> { .handler(context -> {
NamespacedKey namespacedKey = context.get("id"); NamespacedKey namespacedKey = context.get("id");
Key key = Key.of(namespacedKey.namespace(), namespacedKey.value()); Key key = Key.of(namespacedKey.namespace(), namespacedKey.value());
@@ -61,28 +62,19 @@ public class TotemAnimationCommand extends BukkitCommandFeature<CommandSender> {
handleFeedback(context, MessageConstants.COMMAND_TOTEM_NOT_TOTEM, Component.text(key.toString())); handleFeedback(context, MessageConstants.COMMAND_TOTEM_NOT_TOTEM, Component.text(key.toString()));
return; return;
} }
Item<ItemStack> item = customItem.buildItem(ItemBuildContext.empty());
if (VersionHelper.isOrAbove1_21_2()) {
if (context.flags().contains("sound_location")) {
String soundResourceLocation = context.flags().getValue("sound_location").get().toString();
if (soundResourceLocation != null) {
item.setComponent(ComponentTypes.DEATH_PROTECTION, Map.of("death_effects", List.of(Map.of("type", "play_sound", "sound", Map.of(
"sound_id", soundResourceLocation
)))));
}
} else if (context.flags().contains("sound_event")) {
String soundEvent = context.flags().getValue("sound_event").get().toString();
if (soundEvent != null) {
item.setComponent(ComponentTypes.DEATH_PROTECTION, Map.of("death_effects", List.of(Map.of("type", "play_sound", "sound", soundEvent))));
}
} else {
item.setComponent(ComponentTypes.DEATH_PROTECTION, Map.of());
}
}
ItemStack totemItem = item.getItem();
MultiplePlayerSelector selector = context.get("players"); MultiplePlayerSelector selector = context.get("players");
for (Player player : selector.values()) { for (Player player : selector.values()) {
PlayerUtils.sendTotemAnimation(player, totemItem); BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
Item<ItemStack> item = customItem.buildItem(serverPlayer);
if (VersionHelper.isOrAbove1_21_2()) {
item.setJavaComponent(ComponentTypes.DEATH_PROTECTION, Map.of());
}
NamespacedKey soundKey = context.flags().get("sound");
SoundData soundData = null;
if (soundKey != null) {
soundData = SoundData.of(KeyUtils.namespacedKey2Key(soundKey), SoundData.SoundValue.FIXED_1, SoundData.SoundValue.FIXED_1);
}
PlayerUtils.sendTotemAnimation(serverPlayer, item, soundData);
} }
}); });
} }

View File

@@ -3547,9 +3547,11 @@ public final class CoreReflections {
); );
public static final Method method$BlockBehaviour$entityInside = requireNonNull( public static final Method method$BlockBehaviour$entityInside = requireNonNull(
VersionHelper.isOrAbove1_21_5() ? VersionHelper.isOrAbove1_21_10()
ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, void.class, new String[]{"entityInside", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Entity, clazz$InsideBlockEffectApplier) : ? ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, void.class, new String[]{"entityInside", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Entity, clazz$InsideBlockEffectApplier, boolean.class)
ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, void.class, new String[]{"entityInside", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Entity) : VersionHelper.isOrAbove1_21_5()
? ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, void.class, new String[]{"entityInside", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Entity, clazz$InsideBlockEffectApplier)
: ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, void.class, new String[]{"entityInside", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Entity)
); );
// 1.21.5+ // 1.21.5+

View File

@@ -1677,4 +1677,19 @@ public final class NetworkReflections {
ReflectionUtils.getConstructor(clazz$ClientboundUpdateAdvancementsPacket, boolean.class, Collection.class, Set.class, Map.class, boolean.class) : ReflectionUtils.getConstructor(clazz$ClientboundUpdateAdvancementsPacket, boolean.class, Collection.class, Set.class, Map.class, boolean.class) :
ReflectionUtils.getConstructor(clazz$ClientboundUpdateAdvancementsPacket, boolean.class, Collection.class, Set.class, Map.class) ReflectionUtils.getConstructor(clazz$ClientboundUpdateAdvancementsPacket, boolean.class, Collection.class, Set.class, Map.class)
); );
public static final Class<?> clazz$ClientboundStopSoundPacket = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"network.protocol.game.PacketPlayOutStopSound",
"network.protocol.game.ClientboundStopSoundPacket"
)
);
public static final Constructor<?> constructor$ClientboundStopSoundPacket = requireNonNull(
ReflectionUtils.getDeclaredConstructor(
clazz$ClientboundStopSoundPacket,
CoreReflections.clazz$ResourceLocation,
CoreReflections.clazz$SoundSource
)
);
} }

View File

@@ -379,7 +379,7 @@ public class BukkitServerPlayer extends Player {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void giveItem(Item<?> item) { public void giveItem(Item<?> item) {
PlayerUtils.giveItem(platformPlayer(), item.count(), (Item<ItemStack>) item); PlayerUtils.giveItem(this, item.count(), (Item<ItemStack>) item);
} }
@Override @Override

View File

@@ -1,22 +1,26 @@
package net.momirealms.craftengine.bukkit.util; package net.momirealms.craftengine.bukkit.util;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.network.BukkitNetworkManager;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemKeys;
import net.momirealms.craftengine.core.sound.SoundData;
import net.momirealms.craftengine.core.sound.SoundSource;
import net.momirealms.craftengine.core.sound.Sounds;
import net.momirealms.craftengine.core.util.RandomUtils; import net.momirealms.craftengine.core.util.RandomUtils;
import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
public final class PlayerUtils { public final class PlayerUtils {
private PlayerUtils() { private PlayerUtils() {
@@ -33,7 +37,7 @@ public final class PlayerUtils {
} }
public static void giveItem(Player player, Item<ItemStack> original, Item<ItemStack> item) { public static void giveItem(Player player, Item<ItemStack> original, Item<ItemStack> item) {
Object serverPlayer = FastNMS.INSTANCE.method$CraftPlayer$getHandle(player); Object serverPlayer = player.serverPlayer();
Object inventory = FastNMS.INSTANCE.method$Player$getInventory(serverPlayer); Object inventory = FastNMS.INSTANCE.method$Player$getInventory(serverPlayer);
boolean flag = FastNMS.INSTANCE.method$Inventory$add(inventory, item.getLiteralObject()); boolean flag = FastNMS.INSTANCE.method$Inventory$add(inventory, item.getLiteralObject());
if (flag && item.isEmpty()) { if (flag && item.isEmpty()) {
@@ -41,36 +45,57 @@ public final class PlayerUtils {
if (droppedItem != null) { if (droppedItem != null) {
FastNMS.INSTANCE.method$ItemEntity$makeFakeItem(droppedItem); FastNMS.INSTANCE.method$ItemEntity$makeFakeItem(droppedItem);
} }
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 0.2F, ((RandomUtils.generateRandomFloat(0, 1) - RandomUtils.generateRandomFloat(0, 1)) * 0.7F + 1.0F) * 2.0F); player.world().playSound(player.position(), Sounds.ENTITY_ITEM_PICKUP, 0.2F, ((RandomUtils.generateRandomFloat(0, 1) - RandomUtils.generateRandomFloat(0, 1)) * 0.7F + 1.0F) * 2.0F, SoundSource.PLAYER);
FastNMS.INSTANCE.method$AbstractContainerMenu$broadcastChanges(FastNMS.INSTANCE.field$Player$containerMenu(serverPlayer)); FastNMS.INSTANCE.method$AbstractContainerMenu$broadcastChanges(FastNMS.INSTANCE.field$Player$containerMenu(serverPlayer));
} else { } else {
Object droppedItem = FastNMS.INSTANCE.method$ServerPlayer$drop(serverPlayer, item.getLiteralObject(), false, false, !VersionHelper.isOrAbove1_21_5(), null); Object droppedItem = FastNMS.INSTANCE.method$ServerPlayer$drop(serverPlayer, item.getLiteralObject(), false, false, !VersionHelper.isOrAbove1_21_5(), null);
if (droppedItem != null) { if (droppedItem != null) {
FastNMS.INSTANCE.method$ItemEntity$setNoPickUpDelay(droppedItem); FastNMS.INSTANCE.method$ItemEntity$setNoPickUpDelay(droppedItem);
FastNMS.INSTANCE.method$ItemEntity$setTarget(droppedItem, player.getUniqueId()); FastNMS.INSTANCE.method$ItemEntity$setTarget(droppedItem, player.uuid());
} }
} }
} }
public static void sendTotemAnimation(Player player, ItemStack totem) { public static void sendTotemAnimation(Player player, Item<ItemStack> totem, @Nullable SoundData sound) {
ItemStack offhandItem = player.getInventory().getItemInOffHand();
List<Object> packets = new ArrayList<>(); List<Object> packets = new ArrayList<>();
try { try {
Object previousItem = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(offhandItem); Object totemItem = totem.getLiteralObject();
Object totemItem = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(totem); Item<?> previousMainHandItem = player.getItemInHand(InteractionHand.MAIN_HAND);
boolean flag = previousMainHandItem.id().equals(ItemKeys.TOTEM_OF_UNDYING);
Object previousOffHandItem = player.getItemInHand(InteractionHand.OFF_HAND).getLiteralObject();
Object packet1 = NetworkReflections.constructor$ClientboundSetEquipmentPacket if (flag) {
.newInstance(player.getEntityId(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$OFFHAND, totemItem))); packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
Object packet2 = NetworkReflections.constructor$ClientboundEntityEventPacket player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$MAINHAND, BukkitItemManager.instance().uniqueEmptyItem().item().getLiteralObject()))
.newInstance(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player), (byte) 35); ));
Object packet3 = NetworkReflections.constructor$ClientboundSetEquipmentPacket }
.newInstance(player.getEntityId(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$OFFHAND, previousItem))); packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
packets.add(packet1); player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$OFFHAND, totemItem))
packets.add(packet2); ));
packets.add(packet3); packets.add(NetworkReflections.constructor$ClientboundEntityEventPacket.newInstance(player.serverPlayer(), (byte) 35));
if (flag) {
packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$MAINHAND, previousMainHandItem.getLiteralObject()))
));
}
packets.add(NetworkReflections.constructor$ClientboundSetEquipmentPacket.newInstance(
player.entityID(), List.of(Pair.of(CoreReflections.instance$EquipmentSlot$OFFHAND, previousOffHandItem))
));
Object bundlePacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets); if (sound != null) {
BukkitNetworkManager.instance().sendPacket(BukkitAdaptors.adapt(player), bundlePacket); packets.add(NetworkReflections.constructor$ClientboundStopSoundPacket.newInstance(
FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "item.totem.use"),
CoreReflections.instance$SoundSource$PLAYERS
));
packets.add(FastNMS.INSTANCE.constructor$ClientboundSoundPacket(
FastNMS.INSTANCE.method$Holder$direct(FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(sound.id()), Optional.empty())),
CoreReflections.instance$SoundSource$PLAYERS,
player.x(), player.y(), player.z(), sound.volume().get(), sound.pitch().get(),
RandomUtils.generateRandomLong()
));
}
player.sendPackets(packets, false);
} catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) {
BukkitCraftEngine.instance().logger().warn("Failed to send totem animation"); BukkitCraftEngine.instance().logger().warn("Failed to send totem animation");
} }

View File

@@ -100,8 +100,7 @@ public abstract class BlockBehavior {
return false; return false;
} }
// 1.20.1~1.21.8 BlockState state, Level level, BlockPos pos // BlockState state, Level level, BlockPos pos
// 1.21.9+ BlockState state, Level level, BlockPos pos
public int getAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception { public int getAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception {
return 0; return 0;
} }
@@ -143,6 +142,7 @@ public abstract class BlockBehavior {
// 1.20-1.21.4 BlockState state, Level level, BlockPos pos, Entity entity // 1.20-1.21.4 BlockState state, Level level, BlockPos pos, Entity entity
// 1.21.5+ BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier // 1.21.5+ BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier
// 1.21.10+ BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier, boolean flag
public void entityInside(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception { public void entityInside(Object thisBlock, Object[] args, Callable<Object> superMethod) throws Exception {
} }

View File

@@ -43,4 +43,5 @@ public final class Sounds {
public static final Key BAMBOO_WOOD_BUTTON_CLICK_ON = Key.of("block.bamboo_wood_button.click_on"); public static final Key BAMBOO_WOOD_BUTTON_CLICK_ON = Key.of("block.bamboo_wood_button.click_on");
public static final Key WOODEN_BUTTON_CLICK_OFF = Key.of("block.wooden_button.click_off"); public static final Key WOODEN_BUTTON_CLICK_OFF = Key.of("block.wooden_button.click_off");
public static final Key WOODEN_BUTTON_CLICK_ON = Key.of("block.wooden_button.click_on"); public static final Key WOODEN_BUTTON_CLICK_ON = Key.of("block.wooden_button.click_on");
public static final Key ENTITY_ITEM_PICKUP = Key.of("entity.item.pickup");
} }

View File

@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.5 snake_yaml_version=2.5
anti_grief_version=0.20 anti_grief_version=0.20
nms_helper_version=1.0.100 nms_helper_version=1.0.101
evalex_version=3.5.0 evalex_version=3.5.0
reactive_streams_version=1.0.4 reactive_streams_version=1.0.4
amazon_awssdk_version=2.34.5 amazon_awssdk_version=2.34.5