diff --git a/src/main/java/me/tofaa/entitylib/EntityLib.java b/src/main/java/me/tofaa/entitylib/EntityLib.java index 8cab681..01237f4 100644 --- a/src/main/java/me/tofaa/entitylib/EntityLib.java +++ b/src/main/java/me/tofaa/entitylib/EntityLib.java @@ -3,6 +3,7 @@ package me.tofaa.entitylib; import com.github.retrooper.packetevents.PacketEventsAPI; import com.github.retrooper.packetevents.event.PacketListenerAbstract; import com.github.retrooper.packetevents.event.PacketReceiveEvent; +import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.packettype.PacketType; import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; @@ -10,8 +11,11 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper; import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity; import me.tofaa.entitylib.entity.EntityInteractionProcessor; import me.tofaa.entitylib.entity.WrapperEntity; +import me.tofaa.entitylib.entity.WrapperLivingEntity; +import me.tofaa.entitylib.exception.InvalidVersionException; import me.tofaa.entitylib.meta.EntityMeta; import me.tofaa.entitylib.meta.Metadata; +import me.tofaa.entitylib.meta.types.LivingEntityMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -87,7 +91,13 @@ public final class EntityLib { int id = WrapperEntity.ID_PROVIDER.provide(); EntityMeta meta = createMeta(id, entityType); if (meta == null) return null; - WrapperEntity entity = new WrapperEntity(uuid, entityType, meta); + WrapperEntity entity; + if (meta instanceof LivingEntityMeta) { + entity = new WrapperLivingEntity(uuid, entityType, meta); + } + else { + entity = new WrapperEntity(uuid, entityType, meta); + } entities.put(uuid, entity); entitiesById.put(id, entity); return entity; @@ -145,6 +155,12 @@ public final class EntityLib { EntityLib.interactionProcessor = interactionProcessor; } + public static void verifyVersion(ServerVersion supported, String msg) { + if (packetEvents.getServerManager().getVersion().isOlderThan(supported)) { + throw new InvalidVersionException(msg); + } + } + private static void checkInit() { if (!initialized) { throw new IllegalStateException("EntityLib is not initialized"); diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java b/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java index 6d677ba..bcaa565 100644 --- a/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java +++ b/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java @@ -4,10 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.protocol.world.Location; import com.github.retrooper.packetevents.wrapper.PacketWrapper; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity; +import com.github.retrooper.packetevents.wrapper.play.server.*; import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.meta.EntityMeta; import org.jetbrains.annotations.NotNull; @@ -23,7 +20,6 @@ public class WrapperEntity { private final Optional uuid; private final EntityMeta meta; private final Set viewers = new HashSet<>(); - private Location location; private boolean onGround; private boolean spawned; @@ -61,8 +57,8 @@ public class WrapperEntity { ); } - public @NotNull Collection getViewers() { - return Collections.unmodifiableCollection(viewers); + public void rotateHead(Location location) { + rotateHead(location.getYaw(), location.getPitch()); } @@ -80,6 +76,10 @@ public class WrapperEntity { ); } + public @NotNull Collection getViewers() { + return Collections.unmodifiableCollection(viewers); + } + public void teleport(Location location) { teleport(location, true); } diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperEntityEquipment.java b/src/main/java/me/tofaa/entitylib/entity/WrapperEntityEquipment.java new file mode 100644 index 0000000..a834d1c --- /dev/null +++ b/src/main/java/me/tofaa/entitylib/entity/WrapperEntityEquipment.java @@ -0,0 +1,116 @@ +package me.tofaa.entitylib.entity; + +import com.github.retrooper.packetevents.manager.server.ServerVersion; +import com.github.retrooper.packetevents.protocol.item.ItemStack; +import com.github.retrooper.packetevents.protocol.player.Equipment; +import com.github.retrooper.packetevents.protocol.player.EquipmentSlot; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment; +import me.tofaa.entitylib.EntityLib; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class WrapperEntityEquipment { + + private static final EquipmentSlot[] EQUIPMENT_SLOTS = EquipmentSlot.values(); + + private final WrapperLivingEntity entity; + + + // 0 = main hand, 1 = offhand, 2 = boots, 3 = leggings, 4 = chestplate, 5 = helmet + private final ItemStack[] equipment = new ItemStack[6]; + + public WrapperEntityEquipment(WrapperLivingEntity entity) { + this.entity = entity; + Arrays.fill(equipment, ItemStack.EMPTY); + } + + public void setHelmet(@NotNull ItemStack itemStack) { + equipment[5] = itemStack; + refresh(); + } + + public void setChestplate(@NotNull ItemStack itemStack) { + equipment[4] = itemStack; + refresh(); + } + + public void setLeggings(@NotNull ItemStack itemStack) { + equipment[3] = itemStack; + refresh(); + } + + public void setBoots(@NotNull ItemStack itemStack) { + equipment[2] = itemStack; + refresh(); + } + + public void setMainHand(@NotNull ItemStack itemStack) { + equipment[0] = itemStack; + refresh(); + } + + public void setOffhand(@NotNull ItemStack itemStack) { + EntityLib.verifyVersion(ServerVersion.V_1_9, "Offhand is only supported on 1.9+"); + equipment[1] = itemStack; + refresh(); + } + + public void setItem(@NotNull EquipmentSlot slot, @NotNull ItemStack itemStack) { + equipment[slot.ordinal()] = itemStack; + refresh(); + } + + public @NotNull ItemStack getItem(@NotNull EquipmentSlot slot) { + ItemStack itemStack = equipment[slot.ordinal()]; + if (itemStack == null) { + return ItemStack.EMPTY; + } + return itemStack; + } + + public @NotNull ItemStack getHelmet() { + return getItem(EquipmentSlot.HELMET); + } + + public @NotNull ItemStack getChestplate() { + return getItem(EquipmentSlot.CHEST_PLATE); + } + + public @NotNull ItemStack getLeggings() { + return getItem(EquipmentSlot.LEGGINGS); + } + + public @NotNull ItemStack getBoots() { + return getItem(EquipmentSlot.BOOTS); + } + + public @NotNull ItemStack getMainHand() { + return getItem(EquipmentSlot.MAIN_HAND); + } + + public @NotNull ItemStack getOffhand() { + EntityLib.verifyVersion(ServerVersion.V_1_9, "Offhand is only supported on 1.9+"); + return getItem(EquipmentSlot.OFF_HAND); + } + + public WrapperPlayServerEntityEquipment createPacket() { + List equipment = new ArrayList<>(); + for (int i = 0; i < this.equipment.length; i++) { + ItemStack itemStack = this.equipment[i]; + if (itemStack == null || itemStack.equals(ItemStack.EMPTY)) continue; + equipment.add(new Equipment(EQUIPMENT_SLOTS[i], itemStack)); + } + return new WrapperPlayServerEntityEquipment( + entity.getEntityId(), + equipment + ); + } + + public void refresh() { + this.entity.sendPacketToViewers(createPacket()); + } + +} diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java b/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java new file mode 100644 index 0000000..9f4d02c --- /dev/null +++ b/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java @@ -0,0 +1,22 @@ +package me.tofaa.entitylib.entity; + +import com.github.retrooper.packetevents.protocol.entity.type.EntityType; +import me.tofaa.entitylib.meta.EntityMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class WrapperLivingEntity extends WrapperEntity{ + + private final WrapperEntityEquipment equipment; + + public WrapperLivingEntity(@NotNull UUID uuid, EntityType entityType, EntityMeta meta) { + super(uuid, entityType, meta); + this.equipment = new WrapperEntityEquipment(this); + } + + public WrapperEntityEquipment getEquipment() { + return equipment; + } + +} diff --git a/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java b/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java index d6fee53..7d44661 100644 --- a/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java +++ b/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java @@ -2,12 +2,16 @@ package me.tofaa.entitylib; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.world.Location; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; import me.tofaa.entitylib.entity.WrapperEntity; +import me.tofaa.entitylib.entity.WrapperLivingEntity; import me.tofaa.entitylib.meta.EntityMeta; +import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -15,7 +19,7 @@ import java.util.UUID; public class TestEntityCommand implements CommandExecutor { - private WrapperEntity entity; + private WrapperLivingEntity entity; @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { @@ -23,7 +27,7 @@ public class TestEntityCommand implements CommandExecutor { Player player = (Player) sender; if (entity == null) { - entity = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.PIG); + entity = (WrapperLivingEntity) EntityLib.createEntity(UUID.randomUUID(), EntityTypes.ZOMBIE); if (entity == null) { player.sendMessage("idk"); return false; @@ -31,7 +35,10 @@ public class TestEntityCommand implements CommandExecutor { entity.addViewer(player.getUniqueId()); entity.spawn(fromBukkit(player.getLocation())); } - + ItemStack held = player.getInventory().getItemInMainHand(); + if (held != null && held.getType() != Material.AIR) { + entity.getEquipment().setBoots(SpigotConversionUtil.fromBukkitItemStack(held)); + } EntityMeta meta = entity.getMeta(); meta.setOnFire(!meta.isOnFire()); meta.setHasGlowingEffect(!meta.hasGlowingEffect());