diff --git a/.idea/workspace.xml b/.idea/workspace.xml index fcc317b..d305e06 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,17 +5,13 @@ - - - + + - - - - - - - + + + + diff --git a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java index 0b6380d..5276ee7 100644 --- a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java +++ b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java @@ -2,6 +2,7 @@ package me.tofaa.entitylib; import com.github.retrooper.packetevents.PacketEventsAPI; import me.tofaa.entitylib.tick.TickContainer; +import me.tofaa.entitylib.wrapper.WrapperEntity; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -25,6 +26,7 @@ public interface EntityLibAPI { void onEnable(); + /** * Creates a wrapped world for the platform specific world. * @param world The platform specific world handle. diff --git a/api/src/main/java/me/tofaa/entitylib/utils/Check.java b/api/src/main/java/me/tofaa/entitylib/utils/Check.java new file mode 100644 index 0000000..82816ea --- /dev/null +++ b/api/src/main/java/me/tofaa/entitylib/utils/Check.java @@ -0,0 +1,64 @@ +package me.tofaa.entitylib.utils; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.text.MessageFormat; +import java.util.Objects; + +/** + * Convenient class to check for common exceptions. Taken from Minestom + */ +public final class Check { + + private Check() {} + + @Contract("null, _ -> fail") + public static void notNull(@Nullable Object object, @NotNull String reason) { + if (Objects.isNull(object)) { + throw new NullPointerException(reason); + } + } + + @Contract("null, _, _ -> fail") + public static void notNull(@Nullable Object object, @NotNull String reason, Object... arguments) { + if (Objects.isNull(object)) { + throw new NullPointerException(MessageFormat.format(reason, arguments)); + } + } + + @Contract("true, _ -> fail") + public static void argCondition(boolean condition, @NotNull String reason) { + if (condition) { + throw new IllegalArgumentException(reason); + } + } + + @Contract("true, _, _ -> fail") + public static void argCondition(boolean condition, @NotNull String reason, Object... arguments) { + if (condition) { + throw new IllegalArgumentException(MessageFormat.format(reason, arguments)); + } + } + + @Contract("_ -> fail") + public static void fail(@NotNull String reason) { + throw new IllegalArgumentException(reason); + } + + @Contract("true, _ -> fail") + public static void stateCondition(boolean condition, @NotNull String reason) { + if (condition) { + throw new IllegalStateException(reason); + } + } + + @Contract("true, _, _ -> fail") + public static void stateCondition(boolean condition, @NotNull String reason, Object... arguments) { + if (condition) { + throw new IllegalStateException(MessageFormat.format(reason, arguments)); + } + } + +} \ No newline at end of file diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java index 3790363..ddc4fda 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java @@ -45,6 +45,10 @@ public class WrapperEntity implements Tickable { this.viewers = new HashSet<>(); } + public boolean spawn(Location location) { + return spawn(null, location); + } + public boolean spawn(WorldWrapper world, Location location) { if (spawned) return false; this.location = location; @@ -117,6 +121,14 @@ public class WrapperEntity implements Tickable { teleport(world, location, onGround); } + public void teleport(@NotNull Location location, boolean onGround) { + teleport(null, location, onGround); + } + + public void teleport(@NotNull Location location) { + teleport(null, location, onGround); + } + /** * Adds a viewer to the viewers set. The viewer will receive all packets and be informed of this addition * @param uuid the uuid of the user to add @@ -160,6 +172,10 @@ public class WrapperEntity implements Tickable { addViewerSilently(user.getUUID()); } + /** + * Removes a viewer from the viewers set of this entity. The viewer will be informed of this removal and will no longer receive any packets + * @param UUID the uuid of the user to remove + */ public void removeViewer(UUID uuid) { if (!viewers.remove(uuid)) { return; @@ -167,6 +183,10 @@ public class WrapperEntity implements Tickable { sendPacket(uuid, new WrapperPlayServerDestroyEntities(entityId)); } + /** + * Removes a viewer from the viewers set of this entity. The viewer will be informed of this removal and will no longer receive any packets + * @param user the user to remove + */ public void removeViewer(User user) { removeViewer(user.getUUID()); } diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java index 5d684f6..a2bc891 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java @@ -22,7 +22,6 @@ public interface Hologram { return new LegacyHologram<>(world, location, lines); } - @NotNull Location getLocation(); @NotNull WorldWrapper getWorld(); diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java new file mode 100644 index 0000000..75e554d --- /dev/null +++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java @@ -0,0 +1,23 @@ +package me.tofaa.entitylib.spigot; + +import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose; +import com.github.retrooper.packetevents.protocol.player.HumanoidArm; +import org.bukkit.entity.Pose; +import org.bukkit.inventory.MainHand; + +public final class ExtraConversionUtil { + + private ExtraConversionUtil() { + + } + + public static EntityPose fromBukkitPose(Pose pose) { + return EntityPose.values()[pose.ordinal()]; + } + + public static HumanoidArm fromBukkitHand(MainHand hand) { + if (hand == MainHand.RIGHT) return HumanoidArm.RIGHT; + return HumanoidArm.LEFT; + } + +} diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java index cecd18e..f01c7b5 100644 --- a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java +++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java @@ -4,8 +4,17 @@ import com.github.retrooper.packetevents.protocol.world.Location; import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; import io.github.retrooper.packetevents.util.SpigotConversionUtil; import me.tofaa.entitylib.common.AbstractWorldWrapper; +import me.tofaa.entitylib.meta.EntityMeta; +import me.tofaa.entitylib.meta.types.LivingEntityMeta; +import me.tofaa.entitylib.meta.types.PlayerMeta; +import me.tofaa.entitylib.utils.Check; import me.tofaa.entitylib.wrapper.WrapperEntity; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; public class SpigotWorld extends AbstractWorldWrapper { @@ -18,7 +27,31 @@ public class SpigotWorld extends AbstractWorldWrapper { @Override public @NotNull T cloneEntity(@NotNull Object platformEntity, @NotNull Location location) { - return null; + Check.stateCondition(!(platformEntity instanceof Entity), "Entity must be a Bukkit entity"); + Entity e = (Entity) platformEntity; + EntityMeta meta = EntityMeta.createMeta(e.getEntityId(), SpigotConversionUtil.fromBukkitEntityType(e.getType())); + meta.setHasNoGravity(!e.hasGravity()); + meta.setCustomNameVisible(e.isCustomNameVisible()); + meta.setCustomName(LegacyComponentSerializer.legacyAmpersand().deserialize(e.getCustomName())); + meta.setPose(ExtraConversionUtil.fromBukkitPose(e.getPose())); + meta.setOnFire(e.getFireTicks() > 0); + meta.setSilent(e.isSilent()); + meta.setHasGlowingEffect(e.isGlowing()); + if (e instanceof LivingEntity) { + LivingEntity le = (LivingEntity) e; + LivingEntityMeta lm = (LivingEntityMeta) meta; + lm.setHealth((float) le.getHealth()); + lm.setFlyingWithElytra(le.isGliding()); + } + if (e instanceof Player) { + Player p = (Player) e; + PlayerMeta pm = (PlayerMeta) meta; + pm.setSneaking(p.isSneaking()); + pm.setSprinting(p.isSprinting()); + pm.setSwimming(p.isSwimming()); + pm.setActiveHand(ExtraConversionUtil.fromBukkitHand(p.getMainHand())); + } + return null; // TODO; } @Override