> getTickContainers();
+
+ /**
+ * Adds a TickContainer to the API. Automatically starts ticking it.
+ * @param tickContainer the TickContainer to add.
+ */
+ void addTickContainer(@NotNull TickContainer, T> tickContainer);
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/EntityUuidProvider.java b/api/src/main/java/me/tofaa/entitylib/EntityUuidProvider.java
new file mode 100644
index 0000000..bbd1f85
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/EntityUuidProvider.java
@@ -0,0 +1,22 @@
+package me.tofaa.entitylib;
+
+import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.UUID;
+
+public interface EntityUuidProvider {
+
+ @NotNull UUID provide(EntityType entityType);
+
+
+ class DefaultEntityUuidProvider implements EntityUuidProvider {
+
+ @Override
+ public @NotNull UUID provide(EntityType entityType) {
+ return UUID.randomUUID();
+ }
+
+ }
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/Platform.java b/api/src/main/java/me/tofaa/entitylib/Platform.java
new file mode 100644
index 0000000..3094a56
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/Platform.java
@@ -0,0 +1,69 @@
+package me.tofaa.entitylib;
+
+import me.tofaa.entitylib.event.EventBus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.logging.Logger;
+
+/**
+ * A generic representation of a platform that EntityLib is running on.
+ * @param The platform handle, for Spigot this would be a JavaPlugin. etc etc.
+ */
+public interface Platform
{
+
+ /**
+ * Gets the entityId integer provider. This can be provided by a platform if needed.
+ * @return the entityId integer provider.
+ */
+ @NotNull EntityIdProvider getEntityIdProvider();
+
+ /**
+ * Gets the UUID provider for entities. This can be provided by a platform if needed.
+ * @return the UUID provider for entities.
+ */
+ @NotNull EntityUuidProvider getEntityUuidProvider();
+
+ /**
+ * Sets the entityId integer provider. This can be provided by a platform if needed.
+ * @param provider the entityId integer provider.
+ */
+ void setEntityIdProvider(@NotNull EntityIdProvider provider);
+
+ /**
+ * Sets the UUID provider for entities. This can be provided by a platform if needed.
+ * @param provider
+ */
+ void setEntityUuidProvider(@NotNull EntityUuidProvider provider);
+
+
+ /**
+ * @return the logger EntityLib uses internally.
+ */
+ @NotNull Logger getLogger();
+
+ /**
+ * Gets the event bus for the platform.
+ * WARNING: If you have {@link APIConfig#shouldUseAsyncEvents()} set to true, cast this to {@link EventBus.Async} when handling cancelled events.
+ * @return
+ */
+ @NotNull EventBus getEventBus();
+
+ /**
+ * Sets up the API for the platform. This method should be called automatically by the platform. Don't call it yourself.
+ * @param settings
+ */
+ void setupApi(@NotNull APIConfig settings);
+
+ /**
+ * @return The API instance.
+ */
+ EntityLibAPI> getAPI();
+
+ /**
+ * @return the platforms name.
+ */
+ String getName();
+
+ @NotNull P getHandle();
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/EntityLibEvent.java b/api/src/main/java/me/tofaa/entitylib/event/EntityLibEvent.java
new file mode 100644
index 0000000..0a22a30
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/EntityLibEvent.java
@@ -0,0 +1,8 @@
+package me.tofaa.entitylib.event;
+
+public interface EntityLibEvent {
+
+ boolean isCancelled();
+
+ void setCancelled(boolean cancelled);
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/EventBus.java b/api/src/main/java/me/tofaa/entitylib/event/EventBus.java
new file mode 100644
index 0000000..d9ab18f
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/EventBus.java
@@ -0,0 +1,61 @@
+package me.tofaa.entitylib.event;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Consumer;
+
+/**
+ * A basic EventBus for scheduling and handling {@link EntityLibEvent}
+ */
+public interface EventBus {
+
+ static @NotNull EventBus newBus(boolean async) {
+ return async ? new EventBusAsync() : new EventBusSync();
+ }
+
+ /**
+ * Adds a listener to the EventBus.
+ * @param listener The listener object
+ * @param The type of {@link EntityLibEvent}
+ */
+ void addListener(@NotNull EventListener listener);
+
+ /**
+ * Adds a listener to the EventBus.
+ * @param eventClass The events class
+ * @param consumer The consumer for the event.
+ * @param The type of {@link EntityLibEvent}
+ */
+ void addListener(@NotNull Class eventClass, @NotNull Consumer consumer);
+
+ /**
+ * Removes a listener from the EventBus.
+ * @param listener the listener object.
+ * @param The type of {@link EntityLibEvent}
+ */
+ void removeListener(@NotNull EventListener listener);
+
+ /**
+ * Calls the event and processes all the attached {@link EventListener} for the event.
+ * If your bus is async, rather than using this, use {@link Async#call(EntityLibEvent, Consumer)} to avoid any race conditions.
+ * @param event the event object to process handlers for.
+ * @return the same event object, but already modified.
+ * @param The type of {@link EntityLibEvent}
+ */
+ @NotNull T call(@NotNull T event);
+
+
+ interface Async extends EventBus {
+
+ /**
+ * A safer way to handle and process an event. Does exactly what {@link EventBus#call(EntityLibEvent)} does but allows you to attach a callback, rather than working with it yourself,
+ * the callback is executed on the thread this is called, and not the main thread.
+ * @param event the event object to process handlers for.
+ * @param completionCallback the callback handled after the event is consumed async
+ * @param The type of {@link EntityLibEvent}
+ */
+ void call(@NotNull T event, @NotNull Consumer completionCallback);
+
+ }
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/EventBusAsync.java b/api/src/main/java/me/tofaa/entitylib/event/EventBusAsync.java
new file mode 100644
index 0000000..60608d5
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/EventBusAsync.java
@@ -0,0 +1,60 @@
+package me.tofaa.entitylib.event;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+final class EventBusAsync implements EventBus.Async {
+
+ private final Map listeners = new ConcurrentHashMap();
+ private final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 4, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
+
+ @Override
+ public void addListener(@NotNull EventListener listener) {
+ if (listeners.containsKey(listener.getEventClass())) {
+ listeners.put(listener.getEventClass(), new HashSet<>());
+ }
+ ((HashSet) listeners.get(listener.getEventClass())).add(listener);
+ }
+
+ @Override
+ public void addListener(@NotNull Class eventClass, @NotNull Consumer consumer) {
+ addListener(EventListener.generateListener(eventClass, consumer));
+
+ }
+
+ @Override
+ public void removeListener(@NotNull EventListener listener) {
+ if (listeners.containsKey(listener.getEventClass())) {
+ ((HashSet) listeners.get(listener.getEventClass())).remove(listener);
+ }
+ }
+
+ @Override
+ public @NotNull T call(@NotNull T event) {
+ executor.execute(() -> dispatchEvent(event));
+ return event;
+ }
+
+
+ private void dispatchEvent(T event) {
+ if (!listeners.containsKey(event.getClass())) return;
+ HashSet> consumers = (HashSet>) listeners.get(event.getClass());
+ consumers.forEach(consumer -> consumer.handle(event));
+ }
+
+
+ @Override
+ public void call(@NotNull T event, @NotNull Consumer completionCallback) {
+ executor.execute(() -> {
+ dispatchEvent(event);
+ completionCallback.accept(event);
+ });
+ }
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/EventBusSync.java b/api/src/main/java/me/tofaa/entitylib/event/EventBusSync.java
new file mode 100644
index 0000000..4ca6b53
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/EventBusSync.java
@@ -0,0 +1,43 @@
+package me.tofaa.entitylib.event;
+
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+
+@SuppressWarnings("unchecked")
+class EventBusSync implements EventBus {
+
+ private final Map listeners = new ConcurrentHashMap();
+
+ @Override
+ public void addListener(@NotNull EventListener listener) {
+ if (listeners.containsKey(listener.getEventClass())) {
+ listeners.put(listener.getEventClass(), new HashSet<>());
+ }
+ ((HashSet) listeners.get(listener.getEventClass())).add(listener);
+ }
+
+ @Override
+ public void addListener(@NotNull Class eventClass, @NotNull Consumer consumer) {
+ addListener(EventListener.generateListener(eventClass, consumer));
+ }
+
+ @Override
+ public void removeListener(@NotNull EventListener listener) {
+ if (listeners.containsKey(listener.getEventClass())) {
+ ((HashSet) listeners.get(listener.getEventClass())).remove(listener);
+ }
+ }
+
+ @Override
+ public @NotNull T call(@NotNull T event) {
+ if (!listeners.containsKey(event.getClass())) return event;
+ HashSet> consumers = (HashSet>) listeners.get(event.getClass());
+ consumers.forEach(consumer -> consumer.handle(event));
+ return event;
+ }
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/EventListener.java b/api/src/main/java/me/tofaa/entitylib/event/EventListener.java
new file mode 100644
index 0000000..f58dddc
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/EventListener.java
@@ -0,0 +1,27 @@
+package me.tofaa.entitylib.event;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Consumer;
+
+public interface EventListener {
+
+ @NotNull Class getEventClass();
+
+ void handle(@NotNull E event);
+
+ static EventListener generateListener(Class eventClass, Consumer consumer) {
+ return new EventListener() {
+ @Override
+ public @NotNull Class getEventClass() {
+ return eventClass;
+ }
+
+ @Override
+ public void handle(@NotNull T event) {
+ consumer.accept(event);
+ }
+ };
+ }
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/types/UserReceiveMetaUpdateEvent.java b/api/src/main/java/me/tofaa/entitylib/event/types/UserReceiveMetaUpdateEvent.java
new file mode 100644
index 0000000..5b5d64f
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/types/UserReceiveMetaUpdateEvent.java
@@ -0,0 +1,30 @@
+package me.tofaa.entitylib.event.types;
+
+import com.github.retrooper.packetevents.protocol.player.User;
+import me.tofaa.entitylib.event.EntityLibEvent;
+import me.tofaa.entitylib.meta.EntityMeta;
+
+public final class UserReceiveMetaUpdateEvent implements EntityLibEvent {
+
+ private final User user;
+ private boolean cancelled;
+ private EntityMeta meta;
+
+ public UserReceiveMetaUpdateEvent(User user) {
+ this.user = user;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return false;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+
+ }
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/event/types/UserRefreshEntityEvent.java b/api/src/main/java/me/tofaa/entitylib/event/types/UserRefreshEntityEvent.java
new file mode 100644
index 0000000..9276cf2
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/event/types/UserRefreshEntityEvent.java
@@ -0,0 +1,36 @@
+package me.tofaa.entitylib.event.types;
+
+import com.github.retrooper.packetevents.protocol.player.User;
+import me.tofaa.entitylib.event.EntityLibEvent;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+
+public class UserRefreshEntityEvent implements EntityLibEvent {
+
+ private final User user;
+ private final WrapperEntity entity;
+ private boolean cancelled;
+
+ public UserRefreshEntityEvent(User user, WrapperEntity entity) {
+ this.user = user;
+ this.entity = entity;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+
+ public WrapperEntity getEntity() {
+ return entity;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+}
diff --git a/src/main/java/me/tofaa/entitylib/extras/Color.java b/api/src/main/java/me/tofaa/entitylib/extras/Color.java
similarity index 93%
rename from src/main/java/me/tofaa/entitylib/extras/Color.java
rename to api/src/main/java/me/tofaa/entitylib/extras/Color.java
index 1403d39..8feba87 100644
--- a/src/main/java/me/tofaa/entitylib/extras/Color.java
+++ b/api/src/main/java/me/tofaa/entitylib/extras/Color.java
@@ -1,6 +1,5 @@
package me.tofaa.entitylib.extras;
-import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity;
import net.kyori.adventure.util.RGBLike;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
diff --git a/src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java b/api/src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java
rename to api/src/main/java/me/tofaa/entitylib/extras/CoordinateUtil.java
diff --git a/src/main/java/me/tofaa/entitylib/extras/DyeColor.java b/api/src/main/java/me/tofaa/entitylib/extras/DyeColor.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/extras/DyeColor.java
rename to api/src/main/java/me/tofaa/entitylib/extras/DyeColor.java
diff --git a/src/main/java/me/tofaa/entitylib/exception/InvalidVersionException.java b/api/src/main/java/me/tofaa/entitylib/extras/InvalidVersionException.java
similarity index 93%
rename from src/main/java/me/tofaa/entitylib/exception/InvalidVersionException.java
rename to api/src/main/java/me/tofaa/entitylib/extras/InvalidVersionException.java
index 70ff2c7..a6d0964 100644
--- a/src/main/java/me/tofaa/entitylib/exception/InvalidVersionException.java
+++ b/api/src/main/java/me/tofaa/entitylib/extras/InvalidVersionException.java
@@ -1,4 +1,4 @@
-package me.tofaa.entitylib.exception;
+package me.tofaa.entitylib.extras;
public class InvalidVersionException extends RuntimeException {
diff --git a/src/main/java/me/tofaa/entitylib/extras/Rotation.java b/api/src/main/java/me/tofaa/entitylib/extras/Rotation.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/extras/Rotation.java
rename to api/src/main/java/me/tofaa/entitylib/extras/Rotation.java
diff --git a/api/src/main/java/me/tofaa/entitylib/extras/VersionChecker.java b/api/src/main/java/me/tofaa/entitylib/extras/VersionChecker.java
new file mode 100644
index 0000000..c381d52
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/extras/VersionChecker.java
@@ -0,0 +1,17 @@
+package me.tofaa.entitylib.extras;
+
+import com.github.retrooper.packetevents.manager.server.ServerVersion;
+import me.tofaa.entitylib.EntityLib;
+
+public final class VersionChecker {
+
+ private VersionChecker() {}
+
+
+ public static void verifyVersion(ServerVersion version, String message) {
+ if (!version.isNewerThanOrEquals(EntityLib.getApi().getPacketEvents().getServerManager().getVersion())) {
+ throw new InvalidVersionException(message);
+ }
+ }
+
+}
diff --git a/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java
similarity index 61%
rename from src/main/java/me/tofaa/entitylib/meta/EntityMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java
index c759d5c..145cc8b 100644
--- a/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java
@@ -6,17 +6,47 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import com.github.retrooper.packetevents.protocol.entity.data.EntityMetadataProvider;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
import me.tofaa.entitylib.EntityLib;
-import me.tofaa.entitylib.exception.InvalidVersionException;
+import me.tofaa.entitylib.extras.InvalidVersionException;
import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiFunction;
+
+import static me.tofaa.entitylib.meta.MetaOffsetConverter.EntityMetaOffsets.*;
public class EntityMeta implements EntityMetadataProvider {
+ private static final MetaConverterRegistry registry = new MetaConverterRegistry();
+ private static final Map metaMap = new ConcurrentHashMap<>();
+
+ public static @NotNull BiFunction getConverter(EntityType entityType) {
+ return registry.get(entityType);
+ }
+
+ public static @NotNull Class extends EntityMeta> getMetaClass(EntityType entityType) {
+ return registry.getMetaClass(entityType);
+ }
+
+ public static @NotNull EntityMeta createMeta(int entityId, EntityType entityType) {
+ Metadata metadata = new Metadata(entityId);
+ BiFunction converter = getConverter(entityType);
+ EntityMeta entityMeta = converter.apply(entityId, metadata);
+ metaMap.put(entityId, entityMeta);
+ return entityMeta;
+ }
+
+ public static @Nullable EntityMeta getMeta(int entityId) {
+ return metaMap.get(entityId);
+ }
+
public static final byte OFFSET = 0;
public static final byte MAX_OFFSET = OFFSET + 8;
@@ -36,6 +66,14 @@ public class EntityMeta implements EntityMetadataProvider {
this.metadata = metadata;
}
+ public void setNotifyAboutChanges(boolean notifyAboutChanges) {
+ metadata.setNotifyAboutChanges(notifyAboutChanges);
+ }
+
+ public boolean isNotifyingChanges() {
+ return metadata.isNotifyingChanges();
+ }
+
public boolean isOnFire() {
return getMaskBit(OFFSET, ON_FIRE_BIT);
}
@@ -68,30 +106,6 @@ public class EntityMeta implements EntityMetadataProvider {
setMaskBit(OFFSET, INVISIBLE_BIT, value);
}
- public short getAirTicks() {
- return this.metadata.getIndex((byte) 1, (short) 300);
- }
-
- public void setAirTicks(short value) {
- this.metadata.setIndex((byte) 1, EntityDataTypes.SHORT, value);
- }
-
- public Component getCustomName() {
- return this.metadata.getIndex(offset(OFFSET, 2), null);
- }
-
- public void setCustomName(Component value) {
- this.metadata.setIndex(offset(OFFSET, 2), EntityDataTypes.ADV_COMPONENT, value);
- }
-
- public boolean isCustomNameVisible() {
- return this.metadata.getIndex(offset(OFFSET, 3), false);
- }
-
- public void setCustomNameVisible(boolean value) {
- this.metadata.setIndex(offset(OFFSET, 3), EntityDataTypes.BOOLEAN, value);
- }
-
public boolean hasGlowingEffect() {
return getMaskBit(OFFSET, HAS_GLOWING_EFFECT_BIT);
}
@@ -116,60 +130,78 @@ public class EntityMeta implements EntityMetadataProvider {
setMaskBit(OFFSET, FLYING_WITH_ELYTRA_BIT, value);
}
+ public short getAirTicks() {
+ return this.metadata.getIndex(airTicksOffset(), (short) 300);
+ }
+
+ public void setAirTicks(short value) {
+ this.metadata.setIndex(airTicksOffset(), EntityDataTypes.SHORT, value);
+ }
+
+ public Component getCustomName() {
+ return this.metadata.getIndex(customNameOffset(), null);
+ }
+
+ public void setCustomName(Component value) {
+ this.metadata.setIndex(customNameOffset(), EntityDataTypes.ADV_COMPONENT, value);
+ }
+
+ public boolean isCustomNameVisible() {
+ return this.metadata.getIndex(customNameVisibleOffset(), false);
+ }
+
+ public void setCustomNameVisible(boolean value) {
+ this.metadata.setIndex(customNameVisibleOffset(), EntityDataTypes.BOOLEAN, value);
+ }
+
public boolean isSilent() {
- return this.metadata.getIndex((byte) 4, false);
+ return this.metadata.getIndex(silentOffset(), false);
}
public void setSilent(boolean value) {
- this.metadata.setIndex((byte) 4, EntityDataTypes.BOOLEAN, value);
+ this.metadata.setIndex(silentOffset(), EntityDataTypes.BOOLEAN, value);
}
- public boolean isHasNoGravity() {
- return this.metadata.getIndex(offset(OFFSET, 5), true);
+ public boolean hasNoGravity() {
+ return this.metadata.getIndex(hasNoGravityOffset(), true);
}
public void setHasNoGravity(boolean value) {
- this.metadata.setIndex(offset(OFFSET, 5), EntityDataTypes.BOOLEAN, value);
+ this.metadata.setIndex(hasNoGravityOffset(), EntityDataTypes.BOOLEAN, value);
}
public EntityPose getPose() {
- return this.metadata.getIndex(offset(OFFSET, 6), EntityPose.STANDING);
+ return this.metadata.getIndex(poseOffset(), EntityPose.STANDING);
}
public void setPose(EntityPose value) {
- this.metadata.setIndex(offset(OFFSET, 6), EntityDataTypes.ENTITY_POSE, value);
+ this.metadata.setIndex(poseOffset(), EntityDataTypes.ENTITY_POSE, value);
}
public int getTicksFrozenInPowderedSnow() {
- return this.metadata.getIndex(offset(OFFSET, 7), 0);
+ return this.metadata.getIndex(ticksFrozenInPowderedSnowOffset(), 0);
}
public void setTicksFrozenInPowderedSnow(int value) {
- this.metadata.setIndex(offset(OFFSET, 7), EntityDataTypes.INT, value);
+ this.metadata.setIndex(ticksFrozenInPowderedSnowOffset(), EntityDataTypes.INT, value);
}
public WrapperPlayServerEntityMetadata createPacket() {
return metadata.createPacket();
}
- protected static void isVersionOlder(ServerVersion version) {
- if (!EntityLib.getPacketEvents().getServerManager().getVersion().is(VersionComparison.OLDER_THAN, version)) {
- throw new InvalidVersionException("This method is only available for versions older than " + version.name() + ".");
- }
- }
-
protected static void isVersionNewer(ServerVersion version) {
- if (!EntityLib.getPacketEvents().getServerManager().getVersion().is(VersionComparison.NEWER_THAN, version)) {
+ if (!EntityLib.getApi().getPacketEvents().getServerManager().getVersion().is(VersionComparison.NEWER_THAN, version)) {
throw new InvalidVersionException("This method is only available for versions newer than " + version.name() + ".");
}
}
protected static boolean isVersion(ServerVersion version, VersionComparison comparison) {
- return EntityLib.getPacketEvents().getServerManager().getVersion().is(comparison, version);
+ return EntityLib.getApi().getPacketEvents().getServerManager().getVersion().is(comparison, version);
}
protected static boolean isVersion(ServerVersion version) {
- return EntityLib.getPacketEvents().getServerManager().getVersion().is(VersionComparison.EQUALS, version);
+ return EntityLib.getApi().getPacketEvents().getServerManager().getVersion().is(VersionComparison.EQUALS, version);
}
/**
@@ -182,19 +214,19 @@ public class EntityMeta implements EntityMetadataProvider {
return (byte) (value + amount);
}
- protected byte getMask(byte index) {
+ public byte getMask(byte index) {
return this.metadata.getIndex(index, (byte) 0);
}
- protected void setMask(byte index, byte mask) {
+ public void setMask(byte index, byte mask) {
this.metadata.setIndex(index, EntityDataTypes.BYTE, mask);
}
- protected boolean getMaskBit(byte index, byte bit) {
+ public boolean getMaskBit(byte index, byte bit) {
return (getMask(index) & bit) == bit;
}
- protected void setMaskBit(int index, byte bit, boolean value) {
+ public void setMaskBit(int index, byte bit, boolean value) {
byte mask = getMask((byte)index);
boolean currentValue = (mask & bit) == bit;
if (currentValue == value) {
@@ -217,4 +249,6 @@ public class EntityMeta implements EntityMetadataProvider {
public List entityData() {
return metadata.getEntries();
}
+
+
}
diff --git a/src/main/java/me/tofaa/entitylib/MetaConverterRegistry.java b/api/src/main/java/me/tofaa/entitylib/meta/MetaConverterRegistry.java
similarity index 98%
rename from src/main/java/me/tofaa/entitylib/MetaConverterRegistry.java
rename to api/src/main/java/me/tofaa/entitylib/meta/MetaConverterRegistry.java
index dc41653..8aacac4 100644
--- a/src/main/java/me/tofaa/entitylib/MetaConverterRegistry.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/MetaConverterRegistry.java
@@ -1,4 +1,4 @@
-package me.tofaa.entitylib;
+package me.tofaa.entitylib.meta;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import me.tofaa.entitylib.meta.EntityMeta;
@@ -164,8 +164,8 @@ final class MetaConverterRegistry {
metaClasses.put(entityType, metaClass);
}
- public Class getMetaClass(EntityType entityType) {
- return (Class) metaClasses.get(entityType);
+ public Class extends EntityMeta> getMetaClass(EntityType entityType) {
+ return metaClasses.getOrDefault(entityType, EntityMeta.class);
}
public @NotNull BiFunction get(EntityType entityType) {
diff --git a/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java b/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java
new file mode 100644
index 0000000..aaae37b
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java
@@ -0,0 +1,435 @@
+// This class is generated by code-gen module. Do not edit manually.
+//
+package me.tofaa.entitylib.meta;
+
+import static me.tofaa.entitylib.EntityLib.getApi;
+
+import org.jetbrains.annotations.ApiStatus;
+
+@ApiStatus.Internal
+@SuppressWarnings("unused")
+public final class MetaOffsetConverter {
+ private MetaOffsetConverter() {
+
+ }
+
+ public static final class EntityMetaOffsets {
+ public static byte airTicksOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 1;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte customNameOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 2;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte customNameVisibleOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 3;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte silentOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 4;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte hasNoGravityOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 5;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte poseOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 6;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte ticksFrozenInPowderedSnowOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 47 && protocolVersion <= 765) {
+ return 7;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+ }
+
+ public static final class AbstractDisplayMetaOffsets {
+ public static byte interpolationDelayOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 762 && protocolVersion <= 765) {
+ return 8;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte transformationDurationOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 762 && protocolVersion <= 765) {
+ return 9;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte positionRotationInterpolationDurationOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 10;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte translationOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 11;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 10;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte scaleOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 12;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 11;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte leftRotationOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 13;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 12;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte rightRotationOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 14;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 13;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte billboardConstraintsOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 15;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 14;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte brightnessOverrideOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 16;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 15;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte viewRangeOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 17;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 16;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte shadowRadiusOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 18;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 17;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte shadowStrengthOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 19;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 18;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte widthOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 20;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 19;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte heightOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 21;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 20;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte glowColorOverrideOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 22;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 21;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+ }
+
+ public static final class BlockDisplayMetaOffsets {
+ public static byte blockIdOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 23;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 22;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+ }
+
+ public static final class ItemDisplayMetaOffsets {
+ public static byte itemOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 24;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 23;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte displayTypeOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 25;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 24;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+ }
+
+ public static final class TextDisplayMetaOffsets {
+ public static byte textOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 26;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 25;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte textColorOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 27;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 26;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte textBackgroundColorOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 28;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 27;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte textBackgroundOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 29;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 28;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte textScaleOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 30;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 29;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte textAlignmentOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 31;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 30;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte lineWidthOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 32;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 31;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte backgroundColorOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 33;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 32;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte textOpacityOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 34;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 33;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte shadowOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 35;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 34;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte seeThroughOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 36;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 35;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte useDefaultBackgroundOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 37;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 36;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte allighnLeftOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 38;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 37;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte allighnRightOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 39;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 38;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+
+ public static byte allighnCenterOffset() {
+ int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion();
+ if (protocolVersion >= 764 && protocolVersion <= 765) {
+ return 40;
+ }
+ if (protocolVersion >= 762 && protocolVersion <= 763) {
+ return 39;
+ }
+ throw new RuntimeException("Unknown protocol version for this method");
+ }
+ }
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java b/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java
new file mode 100644
index 0000000..5e34240
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java
@@ -0,0 +1,92 @@
+package me.tofaa.entitylib.meta;
+
+import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
+import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
+import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import java.util.*;
+
+@SuppressWarnings("unchecked")
+public class Metadata {
+
+ private final int entityId;
+ private EntityData[] entries = new EntityData[0];
+ private volatile Map entryMap = null;
+ private volatile boolean notifyChanges = true;
+ private final Map notNotifiedChanges = new HashMap<>();
+
+ public Metadata(int entityId) {
+ this.entityId = entityId;
+ }
+
+ public T getIndex(byte index, @Nullable T defaultValue) {
+ final EntityData[] entries = this.entries;
+ if (index < 0 || index >= entries.length) {
+ return defaultValue;
+ }
+ final EntityData entry = entries[index];
+ if (entry == null) return defaultValue;
+ if (entry.getValue() == null) return defaultValue;
+ return (T) entry.getValue();
+ }
+
+ public void setIndex(byte index, @NotNull EntityDataType dataType, T value) {
+
+ EntityData[] entries = this.entries;
+ if (index >= entries.length) {
+ final int newLength = Math.max(entries.length * 2, index + 1);
+ this.entries = entries = Arrays.copyOf(entries, newLength);
+ }
+
+ EntityData data = new EntityData(index, dataType, value);
+ entries[index] = data;
+ this.entryMap = null;
+
+ final WrapperEntity entity = EntityLib.getApi().getEntity(entityId);
+ if (entity == null || entity.isSpawned()) return; // Not EntityLib entity then, the user must send the packet manually. OR not spawned.
+ if (!this.notifyChanges) {
+ synchronized (this.notNotifiedChanges) {
+ this.notNotifiedChanges.put(index, data);
+ }
+ }
+ else {
+ entity.sendPacketToViewers(createPacket());
+ }
+ }
+
+ public void setNotifyAboutChanges(boolean value) {
+ if (this.notifyChanges == value) {
+ return;
+ }
+ if (!notifyChanges) {
+ return; // cache;
+ }
+ final WrapperEntity entity = EntityLib.getApi().getEntity(entityId);
+ if (entity == null || entity.isSpawned()) return;
+ Map entries;
+ synchronized (this.notNotifiedChanges) {
+ Map awaitingChanges = this.notNotifiedChanges;
+ if (awaitingChanges.isEmpty()) return;
+ entries = Collections.unmodifiableMap(awaitingChanges);
+ awaitingChanges.clear();
+ }
+ entity.sendPacketsToViewers(new WrapperPlayServerEntityMetadata(entityId, new ArrayList<>(entries.values())));
+ }
+
+
+ public boolean isNotifyingChanges() {
+ return notifyChanges;
+ }
+
+ @NotNull List getEntries() {
+ return Collections.unmodifiableList(Arrays.asList(entries));
+ }
+
+ public WrapperPlayServerEntityMetadata createPacket() {
+ return new WrapperPlayServerEntityMetadata(entityId, getEntries());
+ }
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/me/tofaa/entitylib/meta/display/AbstractDisplayMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/display/AbstractDisplayMeta.java
new file mode 100644
index 0000000..7d9ba52
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/meta/display/AbstractDisplayMeta.java
@@ -0,0 +1,255 @@
+package me.tofaa.entitylib.meta.display;
+
+import com.github.retrooper.packetevents.manager.server.ServerVersion;
+import com.github.retrooper.packetevents.manager.server.VersionComparison;
+import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
+import com.github.retrooper.packetevents.util.Quaternion4f;
+import com.github.retrooper.packetevents.util.Vector3f;
+import me.tofaa.entitylib.meta.EntityMeta;
+import me.tofaa.entitylib.meta.Metadata;
+
+public abstract class AbstractDisplayMeta extends EntityMeta {
+
+ public static final byte OFFSET = EntityMeta.MAX_OFFSET;
+ public static final byte MAX_OFFSET;
+ static {
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.NEWER_THAN_OR_EQUALS)) {
+ MAX_OFFSET = OFFSET + 15;
+ }
+ else {
+ MAX_OFFSET = OFFSET + 14;
+ }
+ }
+
+ public AbstractDisplayMeta(int entityId, Metadata metadata) {
+ super(entityId, metadata);
+ isVersionNewer(ServerVersion.V_1_19_3);
+ }
+
+ public int getInterpolationDelay() {
+ return super.metadata.getIndex(OFFSET, 0);
+ }
+
+ public void setInterpolationDelay(int value) {
+ super.metadata.setIndex(OFFSET, EntityDataTypes.INT, value);
+ }
+
+ public int getTransformationInterpolationDuration() {
+ return super.metadata.getIndex(offset(OFFSET, 1), 0);
+ }
+
+ public void setTransformationInterpolationDuration(int value) {
+ super.metadata.setIndex(offset(OFFSET, 1), EntityDataTypes.INT, value);
+ }
+
+ public int getPositionRotationInterpolationDuration() {
+ return super.metadata.getIndex(offset(OFFSET, 2), 0);
+ }
+
+ public void setPositionRotationInterpolationDuration(int value) {
+ super.metadata.setIndex(offset(OFFSET, 2), EntityDataTypes.INT, value);
+ }
+
+ public Vector3f getTranslation() {
+ byte offset = offset(OFFSET, 3);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 2);
+ }
+ return super.metadata.getIndex(offset, Vector3f.zero());
+ }
+
+ public void setTranslation(Vector3f value) {
+ byte offset = offset(OFFSET, 3);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 2);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.VECTOR3F, value);
+ }
+
+ public Vector3f getScale() {
+ byte offset = offset(OFFSET, 4);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 3);
+ }
+ return super.metadata.getIndex(offset, new Vector3f(1.0f, 1.0f, 1.0f));
+ }
+
+ public void setScale(Vector3f value) {
+ byte offset = offset(OFFSET, 4);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 3);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.VECTOR3F, value);
+ }
+
+ public Quaternion4f getLeftRotation() {
+ byte offset = offset(OFFSET, 5);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 4);
+ }
+ return super.metadata.getIndex(offset, new Quaternion4f(0.0f, 0.0f, 0.0f, 1.0f));
+ }
+
+ public void setLeftRotation(Quaternion4f value) {
+ byte offset = offset(OFFSET, 5);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 4);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.QUATERNION, value);
+ }
+
+ public Quaternion4f getRightRotation() {
+ byte offset = offset(OFFSET, 6);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 5);
+ }
+ return super.metadata.getIndex(offset, new Quaternion4f(0.0f, 0.0f, 0.0f, 1.0f));
+ }
+
+ public void setRightRotation(Quaternion4f value) {
+ byte offset = offset(OFFSET, 6);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 5);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.QUATERNION, value);
+ }
+
+ public BillboardConstraints getBillboardConstraints() {
+ byte offset = offset(OFFSET, 7);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 6);
+ }
+ return BillboardConstraints.VALUES[super.metadata.getIndex(offset, (byte) 0)];
+ }
+
+ public void setBillboardConstraints(BillboardConstraints value) {
+ byte offset = offset(OFFSET, 7);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 6);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.BYTE, (byte) value.ordinal());
+ }
+
+ //(blockLight << 4 | skyLight << 20)
+ public int getBrightnessOverride() {
+ byte offset = offset(OFFSET, 8);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 7);
+ }
+ return super.metadata.getIndex(offset, -1);
+ }
+
+ public void setBrightnessOverride(int value) {
+ byte offset = offset(OFFSET, 8);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 7);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.INT, value);
+ }
+
+ public float getViewRange() {
+ byte offset = offset(OFFSET, 9);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 8);
+ }
+ return super.metadata.getIndex(offset, 1.0f);
+ }
+
+ public void setViewRange(float value) {
+ byte offset = offset(OFFSET, 9);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 8);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
+ }
+
+ public float getShadowRadius() {
+ byte offset = offset(OFFSET, 10);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 9);
+ }
+ return super.metadata.getIndex(offset, 0.0f);
+ }
+
+ public void setShadowRadius(float value) {
+ byte offset = offset(OFFSET, 10);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 9);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
+ }
+
+ public float getShadowStrength() {
+ byte offset = offset(OFFSET, 11);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 10);
+ }
+ return super.metadata.getIndex(offset, 1.0f);
+ }
+
+ public void setShadowStrength(float value) {
+ byte offset = offset(OFFSET, 11);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 10);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
+ }
+
+ public float getWidth() {
+ byte offset = offset(OFFSET, 12);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 11);
+ }
+ return super.metadata.getIndex(offset, 0.0f);
+ }
+
+ public void setWidth(float value) {
+ byte offset = offset(OFFSET, 12);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 11);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
+ }
+
+ public float getHeight() {
+ byte offset = offset(OFFSET, 13);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 12);
+ }
+ return super.metadata.getIndex(offset, 0.0f);
+ }
+
+ public void setHeight(float value) {
+ byte offset = offset(OFFSET, 13);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 12);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.FLOAT, value);
+ }
+
+ public int getGlowColorOverride() {
+ byte offset = offset(OFFSET, 14);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 13);
+ }
+ return super.metadata.getIndex(offset, -1);
+ }
+
+ public void setGlowColorOverride(int value) {
+ byte offset = offset(OFFSET, 14);
+ if (isVersion(ServerVersion.V_1_20_2, VersionComparison.OLDER_THAN)) {
+ offset = offset(OFFSET, 13);
+ }
+ super.metadata.setIndex(offset, EntityDataTypes.INT, value);
+ }
+
+ public enum BillboardConstraints {
+ FIXED,
+ VERTICAL,
+ HORIZONTAL,
+ CENTER;
+
+ private static final BillboardConstraints[] VALUES = values();
+ }
+
+}
diff --git a/src/main/java/me/tofaa/entitylib/meta/display/BlockDisplayMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/display/BlockDisplayMeta.java
similarity index 76%
rename from src/main/java/me/tofaa/entitylib/meta/display/BlockDisplayMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/display/BlockDisplayMeta.java
index 80cf218..45a077a 100644
--- a/src/main/java/me/tofaa/entitylib/meta/display/BlockDisplayMeta.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/display/BlockDisplayMeta.java
@@ -2,11 +2,10 @@ package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import me.tofaa.entitylib.meta.Metadata;
-import me.tofaa.entitylib.meta.types.DisplayMeta;
-public class BlockDisplayMeta extends DisplayMeta {
+public class BlockDisplayMeta extends AbstractDisplayMeta {
- public static final byte OFFSET = DisplayMeta.MAX_OFFSET;
+ public static final byte OFFSET = AbstractDisplayMeta.MAX_OFFSET;
public static final byte MAX_OFFSET = offset(OFFSET, 1);
public BlockDisplayMeta(int entityId, Metadata metadata) {
diff --git a/src/main/java/me/tofaa/entitylib/meta/display/ItemDisplayMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/display/ItemDisplayMeta.java
similarity index 88%
rename from src/main/java/me/tofaa/entitylib/meta/display/ItemDisplayMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/display/ItemDisplayMeta.java
index eee43fe..7668dfc 100644
--- a/src/main/java/me/tofaa/entitylib/meta/display/ItemDisplayMeta.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/display/ItemDisplayMeta.java
@@ -3,11 +3,10 @@ package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import me.tofaa.entitylib.meta.Metadata;
-import me.tofaa.entitylib.meta.types.DisplayMeta;
-public class ItemDisplayMeta extends DisplayMeta {
+public class ItemDisplayMeta extends AbstractDisplayMeta {
- public static final byte OFFSET = DisplayMeta.MAX_OFFSET;
+ public static final byte OFFSET = AbstractDisplayMeta.MAX_OFFSET;
public static final byte MAX_OFFSET = offset(OFFSET, 1);
public ItemDisplayMeta(int entityId, Metadata metadata) {
@@ -45,3 +44,4 @@ public class ItemDisplayMeta extends DisplayMeta {
}
}
+
diff --git a/src/main/java/me/tofaa/entitylib/meta/display/TextDisplayMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/display/TextDisplayMeta.java
similarity index 94%
rename from src/main/java/me/tofaa/entitylib/meta/display/TextDisplayMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/display/TextDisplayMeta.java
index 314323b..85ef64e 100644
--- a/src/main/java/me/tofaa/entitylib/meta/display/TextDisplayMeta.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/display/TextDisplayMeta.java
@@ -2,12 +2,11 @@ package me.tofaa.entitylib.meta.display;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import me.tofaa.entitylib.meta.Metadata;
-import me.tofaa.entitylib.meta.types.DisplayMeta;
import net.kyori.adventure.text.Component;
-public class TextDisplayMeta extends DisplayMeta {
+public class TextDisplayMeta extends AbstractDisplayMeta {
- public static final byte OFFSET = DisplayMeta.MAX_OFFSET;
+ public static final byte OFFSET = AbstractDisplayMeta.MAX_OFFSET;
public static final byte MAX_OFFSET = offset(OFFSET, 5);
private static final byte SHADOW = 1;
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/BatMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/BatMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/BatMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/BatMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/BeeMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/BeeMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/BeeMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/BeeMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/DonkeyMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/DonkeyMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/DonkeyMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/DonkeyMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/FoxMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/FoxMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/FoxMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/FoxMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/FrogMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/FrogMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/FrogMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/FrogMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/GoatMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/GoatMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/GoatMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/GoatMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/HoglinMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/HoglinMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/HoglinMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/HoglinMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/OcelotMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/OcelotMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/OcelotMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/OcelotMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/PandaMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/PandaMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/PandaMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/PandaMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/PolarBearMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/PolarBearMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/PolarBearMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/PolarBearMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/SnifferMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/SnifferMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/SnifferMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/SnifferMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/StriderMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/StriderMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/StriderMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/StriderMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/MagmaCubeMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/MagmaCubeMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/MagmaCubeMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/MagmaCubeMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/SlimeMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/SlimeMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/SlimeMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/cuboid/SlimeMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/golem/IronGolemMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/golem/IronGolemMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/golem/IronGolemMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/golem/IronGolemMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/golem/ShulkerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/golem/ShulkerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/golem/ShulkerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/golem/ShulkerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/golem/SnowGolemMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/golem/SnowGolemMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/golem/SnowGolemMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/golem/SnowGolemMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/BaseHorseMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/BaseHorseMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/BaseHorseMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/BaseHorseMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/ChestedHorseMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/ChestedHorseMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/ChestedHorseMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/ChestedHorseMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/DonkeyMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/DonkeyMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/DonkeyMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/DonkeyMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/HorseMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/HorseMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/HorseMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/HorseMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/LlamaMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/LlamaMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/LlamaMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/LlamaMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/MuleMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/MuleMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/MuleMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/MuleMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/SkeletonHorseMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/SkeletonHorseMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/SkeletonHorseMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/SkeletonHorseMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/TraderLlamaMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/TraderLlamaMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/TraderLlamaMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/TraderLlamaMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/horse/ZombieHorseMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/ZombieHorseMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/horse/ZombieHorseMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/horse/ZombieHorseMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/BaseMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/BaseMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/BaseMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/BaseMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/ChestMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/ChestMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/ChestMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/ChestMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/CommandBlockMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/CommandBlockMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/CommandBlockMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/CommandBlockMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/FurnaceMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/FurnaceMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/FurnaceMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/FurnaceMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/HopperMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/HopperMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/HopperMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/HopperMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/MinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/MinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/MinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/MinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/SpawnerMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/SpawnerMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/SpawnerMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/SpawnerMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/TntMinecartMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/TntMinecartMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/minecart/TntMinecartMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/minecart/TntMinecartMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/BlazeMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/BlazeMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/BlazeMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/BlazeMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/CaveSpiderMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/CaveSpiderMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/CaveSpiderMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/CaveSpiderMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/CreeperMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/CreeperMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/CreeperMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/CreeperMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/ElderGuardianMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/ElderGuardianMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/ElderGuardianMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/ElderGuardianMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermanMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermanMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermanMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermanMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermiteMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermiteMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermiteMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/EndermiteMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GhastMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GhastMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/GhastMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GhastMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GiantMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GiantMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/GiantMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GiantMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GuardianMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GuardianMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/GuardianMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/GuardianMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/PhantomMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/PhantomMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/PhantomMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/PhantomMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/SilverfishMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/SilverfishMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/SilverfishMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/SilverfishMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/SpiderMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/SpiderMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/SpiderMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/SpiderMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/VexMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/VexMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/VexMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/VexMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/WitherMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/WitherMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/WitherMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/WitherMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/ZoglinMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/ZoglinMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/ZoglinMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/ZoglinMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/BasePiglinMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/BasePiglinMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/BasePiglinMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/BasePiglinMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinBruteMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinBruteMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinBruteMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinBruteMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/piglin/PiglinMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/EvokerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/EvokerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/EvokerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/EvokerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/IllusionerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/IllusionerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/IllusionerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/IllusionerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/PillagerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/PillagerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/PillagerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/PillagerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RaiderMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RaiderMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RaiderMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RaiderMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RavagerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RavagerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RavagerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/RavagerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/SpellcasterIllagerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/SpellcasterIllagerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/SpellcasterIllagerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/SpellcasterIllagerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/VindicatorMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/VindicatorMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/VindicatorMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/VindicatorMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/WitchMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/WitchMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/WitchMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/raider/WitchMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/SkeletonMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/SkeletonMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/SkeletonMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/SkeletonMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/StrayMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/StrayMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/StrayMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/StrayMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/WitherSkeletonMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/WitherSkeletonMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/WitherSkeletonMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/skeleton/WitherSkeletonMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/DrownedMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/DrownedMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/DrownedMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/DrownedMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/HuskMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/HuskMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/HuskMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/HuskMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieVillagerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieVillagerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieVillagerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombieVillagerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombifiedPiglinMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombifiedPiglinMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombifiedPiglinMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/monster/zombie/ZombifiedPiglinMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/ChickenMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/ChickenMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/ChickenMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/ChickenMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/CowMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/CowMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/CowMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/CowMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/MooshroomMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/MooshroomMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/MooshroomMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/MooshroomMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/PigMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/PigMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/PigMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/PigMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/RabbitMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/RabbitMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/RabbitMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/RabbitMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/SheepMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/SheepMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/SheepMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/SheepMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/passive/TurtleMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/TurtleMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/passive/TurtleMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/passive/TurtleMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/CatMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/CatMeta.java
similarity index 93%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/tameable/CatMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/CatMeta.java
index 2dde774..5dae395 100644
--- a/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/CatMeta.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/CatMeta.java
@@ -1,11 +1,10 @@
package me.tofaa.entitylib.meta.mobs.tameable;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
-import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import me.tofaa.entitylib.extras.DyeColor;
import me.tofaa.entitylib.meta.Metadata;
import me.tofaa.entitylib.meta.types.TameableMeta;
-import net.kyori.adventure.text.format.NamedTextColor;
+
import org.jetbrains.annotations.NotNull;
public class CatMeta extends TameableMeta {
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/ParrotMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/ParrotMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/tameable/ParrotMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/ParrotMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/WolfMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/WolfMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/tameable/WolfMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/tameable/WolfMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/villager/BaseVillagerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/villager/BaseVillagerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/villager/BaseVillagerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/villager/BaseVillagerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/villager/VillagerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/villager/VillagerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/villager/VillagerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/villager/VillagerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/villager/WanderingTraderMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/villager/WanderingTraderMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/villager/WanderingTraderMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/villager/WanderingTraderMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/AxolotlMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/AxolotlMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/AxolotlMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/AxolotlMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/BaseFishMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/BaseFishMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/BaseFishMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/BaseFishMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/CodMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/CodMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/CodMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/CodMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/DolphinMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/DolphinMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/DolphinMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/DolphinMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/GlowSquidMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/GlowSquidMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/GlowSquidMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/GlowSquidMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/PufferFishMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/PufferFishMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/PufferFishMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/PufferFishMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/SalmonMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/SalmonMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/SalmonMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/SalmonMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/SquidMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/SquidMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/SquidMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/SquidMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/mobs/water/TropicalFishMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/mobs/water/TropicalFishMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/mobs/water/TropicalFishMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/mobs/water/TropicalFishMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/AreaEffectCloudMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/AreaEffectCloudMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/AreaEffectCloudMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/AreaEffectCloudMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/ArmorStandMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/ArmorStandMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/ArmorStandMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/ArmorStandMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/BoatMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/BoatMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/BoatMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/BoatMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/EndCrystalMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/EndCrystalMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/EndCrystalMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/EndCrystalMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/EnderDragonMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/EnderDragonMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/EnderDragonMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/EnderDragonMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/EvokerFangsMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/EvokerFangsMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/EvokerFangsMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/EvokerFangsMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/FallingBlockMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/FallingBlockMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/FallingBlockMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/FallingBlockMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/FireworkRocketMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/FireworkRocketMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/FireworkRocketMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/FireworkRocketMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/FishingHookMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/FishingHookMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/FishingHookMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/FishingHookMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/GlowItemFrameMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/GlowItemFrameMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/GlowItemFrameMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/GlowItemFrameMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/InteractionMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/InteractionMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/InteractionMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/InteractionMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/ItemFrameMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/ItemFrameMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/ItemFrameMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/ItemFrameMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/LeashKnotMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/LeashKnotMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/LeashKnotMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/LeashKnotMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/LightningBoltMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/LightningBoltMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/LightningBoltMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/LightningBoltMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/LlamaSpitMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/LlamaSpitMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/LlamaSpitMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/LlamaSpitMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/MarkerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/MarkerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/MarkerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/MarkerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/PaintingMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/PaintingMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/PaintingMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/PaintingMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/other/PrimedTntMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/other/PrimedTntMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/other/PrimedTntMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/other/PrimedTntMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ArrowMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ArrowMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ArrowMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ArrowMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/BaseArrowMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/BaseArrowMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/BaseArrowMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/BaseArrowMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/DragonFireballMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/DragonFireballMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/DragonFireballMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/DragonFireballMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/EyeOfEnderMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/EyeOfEnderMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/EyeOfEnderMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/EyeOfEnderMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ItemEntityMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ItemEntityMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ItemEntityMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ItemEntityMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/LargeFireballMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/LargeFireballMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/LargeFireballMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/LargeFireballMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ShulkerBulletMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ShulkerBulletMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ShulkerBulletMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ShulkerBulletMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/SmallFireballMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/SmallFireballMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/SmallFireballMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/SmallFireballMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/SnowballMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/SnowballMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/SnowballMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/SnowballMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/SpectralArrowMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/SpectralArrowMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/SpectralArrowMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/SpectralArrowMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEggMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEggMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEggMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEggMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEnderPearlMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEnderPearlMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEnderPearlMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownEnderPearlMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownExpBottleMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownExpBottleMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ThrownExpBottleMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownExpBottleMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownPotionMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownPotionMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ThrownPotionMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownPotionMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownTridentMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownTridentMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/ThrownTridentMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/ThrownTridentMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/projectile/WitherSkullMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/projectile/WitherSkullMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/projectile/WitherSkullMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/projectile/WitherSkullMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/AgeableMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/AgeableMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/AgeableMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/AgeableMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/DisplayMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/ItemContainerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/ItemContainerMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/ItemContainerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/ItemContainerMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/LivingEntityMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/LivingEntityMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/LivingEntityMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/LivingEntityMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/MobMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/MobMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/MobMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/MobMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/ObjectData.java b/api/src/main/java/me/tofaa/entitylib/meta/types/ObjectData.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/ObjectData.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/ObjectData.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/PlayerMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/PlayerMeta.java
similarity index 95%
rename from src/main/java/me/tofaa/entitylib/meta/types/PlayerMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/PlayerMeta.java
index 21b1fc0..d03ab31 100644
--- a/src/main/java/me/tofaa/entitylib/meta/types/PlayerMeta.java
+++ b/api/src/main/java/me/tofaa/entitylib/meta/types/PlayerMeta.java
@@ -112,14 +112,14 @@ public class PlayerMeta extends LivingEntityMeta {
}
public boolean isRightHandMain() {
- if (EntityLib.getPacketEvents().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
+ if (EntityLib.getApi().getPacketEvents().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
return true;
}
return super.metadata.getIndex(offset(OFFSET,3), (byte) 1) == (byte) 1;
}
public void setRightHandMain(boolean value) {
- if (EntityLib.getPacketEvents().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
+ if (EntityLib.getApi().getPacketEvents().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
return;
}
super.metadata.setIndex(offset(OFFSET,3), EntityDataTypes.BYTE, (byte) (value ? 1 : 0));
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/ProjectileMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/ProjectileMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/ProjectileMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/ProjectileMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/TameableMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/TameableMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/TameableMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/TameableMeta.java
diff --git a/src/main/java/me/tofaa/entitylib/meta/types/WaterMobMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/types/WaterMobMeta.java
similarity index 100%
rename from src/main/java/me/tofaa/entitylib/meta/types/WaterMobMeta.java
rename to api/src/main/java/me/tofaa/entitylib/meta/types/WaterMobMeta.java
diff --git a/api/src/main/java/me/tofaa/entitylib/tick/TickContainer.java b/api/src/main/java/me/tofaa/entitylib/tick/TickContainer.java
new file mode 100644
index 0000000..0d9b880
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/tick/TickContainer.java
@@ -0,0 +1,72 @@
+package me.tofaa.entitylib.tick;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Represents a storage/container for {@link Tickable}s. This class is extendable in case you want to provide custom logic and/or methods.
+ * @param The type of {@link Tickable} to store.
+ * @param If a platform enforces a specific method of ticking, this type represents the handler for that method.
+ */
+public class TickContainer {
+
+ private final Set tickables = new HashSet<>();
+ private H handle;
+
+ /**
+ * @return The {@link Tickable}s stored in this container. This collection is immutable
+ */
+ public @NotNull Collection getTickables() {
+ return Collections.unmodifiableCollection(tickables);
+ }
+
+ /**
+ * Adds a {@link Tickable} to this container.
+ * @param tickable The {@link Tickable} to add.
+ * @return {@code true} if the {@link Tickable} was added, {@code false} otherwise.
+ */
+ public boolean addTickable(@NotNull T tickable) {
+ return tickables.add(tickable);
+ }
+
+ /**
+ * Removes a {@link Tickable} from this container.
+ * @param tickable The {@link Tickable} to remove.
+ * @return {@code true} if the {@link Tickable} was removed, {@code false} otherwise.
+ */
+ public boolean removeTickable(T tickable) {
+ return tickables.remove(tickable);
+ }
+
+ /**
+ * Ticks all {@link Tickable}s in this container, this method can be overriden to provide a custom implementation.
+ * @param time The current time in milliseconds, incase the {@link Tickable} needs to know the current time.
+ */
+ public void tick(long time) {
+ for (T tickable : tickables) {
+ tickable.tick(time);
+ }
+ }
+
+ /**
+ * @return The handler for this container.
+ */
+ public @NotNull H getHandle() {
+ return handle;
+ }
+
+ /**
+ * Sets the handler for this container. This method is only used internally.
+ * @param handle The handler to set.
+ */
+ @ApiStatus.Internal
+ public void setHandle(@NotNull H handle) {
+ this.handle = handle;
+ }
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java b/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java
new file mode 100644
index 0000000..4b38f89
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/tick/Tickable.java
@@ -0,0 +1,22 @@
+package me.tofaa.entitylib.tick;
+
+public interface Tickable {
+
+ /**
+ * @return if the entity is ticking.
+ */
+ boolean isTicking();
+
+ /**
+ * Sets the entities ticking status, incase you want to stop ticking for a moment then continue
+ * @param ticking if the entity should tick.
+ */
+ void setTicking(boolean ticking);
+
+ /**
+ * Ticks this entity. This method will not be called if {@link #isTicking()} returns false.
+ * @param time the current time in milliseconds.
+ */
+ void tick(long time);
+
+}
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/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
similarity index 64%
rename from src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
index ddbffcd..0ce32de 100644
--- a/src/main/java/me/tofaa/entitylib/entity/WrapperEntity.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
@@ -1,4 +1,4 @@
-package me.tofaa.entitylib.entity;
+package me.tofaa.entitylib.wrapper;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.player.User;
@@ -7,44 +7,331 @@ import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.*;
import me.tofaa.entitylib.EntityLib;
-import me.tofaa.entitylib.Tickable;
import me.tofaa.entitylib.meta.EntityMeta;
import me.tofaa.entitylib.meta.types.ObjectData;
+import me.tofaa.entitylib.tick.Tickable;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
public class WrapperEntity implements Tickable {
- private final EntityType entityType;
+
+ private final UUID uuid;
private final int entityId;
- private final Optional uuid;
- private final EntityMeta meta;
- private final Set viewers = ConcurrentHashMap.newKeySet();
+ private EntityType entityType;
+ private EntityMeta entityMeta;
+ private boolean ticking;
private Location location;
+ private Location preRidingLocation;
+ private final Set viewers;
private boolean onGround;
private boolean spawned;
- protected Vector3d velocity = Vector3d.zero();
+ private Vector3d velocity;
private int riding = -1;
- private Set passengers = ConcurrentHashMap.newKeySet();
+ private final Set passengers;
- public WrapperEntity(int entityId, @NotNull UUID uuid, EntityType entityType, EntityMeta meta) {
- this.uuid = Optional.of(uuid);
- this.entityType = entityType;
- this.meta = meta;
+ public WrapperEntity(int entityId, UUID uuid, EntityType entityType, EntityMeta entityMeta) {
this.entityId = entityId;
+ this.uuid = uuid;
+ this.entityType = entityType;
+ this.entityMeta = entityMeta;
+ this.ticking = true;
+ this.viewers = new HashSet<>();
+ this.passengers = new HashSet<>();
+ }
+
+ public boolean spawn(Location location) {
+ if (spawned) return false;
+ this.location = location;
+ this.spawned = true;
+ int data = 0;
+ Optional velocity;
+ double veloX = 0, veloY = 0, veloZ = 0;
+ if (entityMeta instanceof ObjectData) {
+ ObjectData od = (ObjectData) entityMeta;
+ data = od.getObjectData();
+ if (od.requiresVelocityPacketAtSpawn()) {
+ final WrapperPlayServerEntityVelocity veloPacket = getVelocityPacket();
+ veloX = veloPacket.getVelocity().getX();
+ veloY = veloPacket.getVelocity().getY();
+ veloZ = veloPacket.getVelocity().getZ();
+ }
+ }
+ if (veloX == 0 && veloY == 0 && veloZ == 0) {
+ velocity = Optional.empty();
+ } else {
+ velocity = Optional.of(new Vector3d(veloX, veloY, veloZ));
+ }
+ sendPacketToViewers(
+ new WrapperPlayServerSpawnEntity(
+ entityId,
+ Optional.of(this.uuid),
+ entityType,
+ location.getPosition(),
+ location.getPitch(),
+ location.getYaw(),
+ location.getYaw(),
+ data,
+ velocity
+ )
+ );
+ sendPacketToViewers(entityMeta.createPacket());
+ return true;
+ }
+
+ public void remove() {
+ EntityLib.getApi().removeEntity(this);
+ }
+
+ public void despawn() {
+ if (!spawned) return;
+ spawned = false;
+ sendPacketToViewers(new WrapperPlayServerDestroyEntities(entityId));
+ }
+
+ public void teleport(@NotNull Location location, boolean onGround) {
+ if (!spawned) {
+ return;
+ }
+ this.location = location;
+ this.onGround = onGround;
+ sendPacketToViewers(
+ new WrapperPlayServerEntityTeleport(
+ entityId,
+ location.getPosition(),
+ location.getYaw(),
+ location.getPitch(),
+ onGround
+ )
+ );
+ }
+
+ public void teleport(@NotNull Location location) {
+ teleport(location, onGround);
}
/**
- Internally sets the location of this entity. This does not inform any of the entities viewers about this change.
- */
- public void setLocation(Location location) {
- this.location = location;
+ * 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
+ */
+ public void addViewer(UUID uuid) {
+ if (!viewers.add(uuid)) {
+ return;
+ }
+ WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(
+ entityId,
+ Optional.of(this.uuid),
+ entityType,
+ location.getPosition(),
+ location.getPitch(),
+ location.getYaw(),
+ location.getYaw(),
+ 0,
+ Optional.empty()
+ );
+ sendPacket(uuid, packet);
+ sendPacket(uuid, entityMeta.createPacket());
+ }
+
+ public void addViewer(User user) {
+ addViewer(user.getUUID());
+ }
+
+ /**
+ * Adds a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this addition
+ * @param uuid the uuid of the user to add
+ */
+ public void addViewerSilently(UUID uuid) {
+ viewers.add(uuid);
+ }
+
+ /**
+ * Adds a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this addition
+ * @param user the user to add
+ */
+ public void addViewerSilently(User user) {
+ 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;
+ }
+ 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());
+ }
+
+ /**
+ * removes a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this removal
+ * @param uuid of the user to remove
+ */
+ public void removeViewerSilently(UUID uuid) {
+ viewers.remove(uuid);
+ }
+
+ /**
+ * removes a viewer silently into the viewers set. The viewer will not receive any packets or be informed of this removal
+ * @param user the user to remove
+ */
+ public void removeViewerSilently(User user) {
+ removeViewerSilently(user.getUUID());
+ }
+
+ public boolean isOnGround() {
+ return onGround;
+ }
+
+ public Vector3d getVelocity() {
+ return velocity;
+ }
+
+ public void setVelocity(Vector3d velocity) {
+ this.velocity = velocity;
+ sendPacketToViewers(getVelocityPacket());
+ }
+
+ public double getX() {
+ return location.getX();
+ }
+
+ public double getY() {
+ return location.getY();
+ }
+
+ public double getZ() {
+ return location.getZ();
+ }
+
+ public float getYaw() {
+ return location.getYaw();
+ }
+
+ public float getPitch() {
+ return location.getPitch();
+ }
+
+ public int getEntityId() {
+ return entityId;
+ }
+
+ public EntityMeta getEntityMeta() {
+ return entityMeta;
+ }
+
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ public EntityType getEntityType() {
+ return entityType;
+ }
+
+ /**
+ * Returns an unmodifiable set of the passengers of the entity.
+ * @return the passengers of the entity
+ */
+ public Set getPassengers() {
+ return Collections.unmodifiableSet(passengers);
+ }
+
+ public WrapperEntity getRiding() {
+ return EntityLib.getApi().getEntity(riding);
+ }
+
+ protected WrapperPlayServerSetPassengers createPassengerPacket() {
+ return new WrapperPlayServerSetPassengers(entityId, passengers.stream().mapToInt(i -> i).toArray());
+ }
+
+
+ private WrapperPlayServerEntityVelocity getVelocityPacket() {
+ Vector3d velocity = this.velocity.multiply(8000.0f / 20.0f);
+ return new WrapperPlayServerEntityVelocity(entityId, velocity);
+ }
+
+ public boolean isSpawned() {
+ return spawned;
+ }
+
+ @Override
+ public boolean isTicking() {
+ return ticking;
+ }
+
+ @Override
+ public void setTicking(boolean ticking) {
+ this.ticking = ticking;
+ }
+
+ public boolean hasVelocity() {
+ if (isOnGround()) {
+ // if the entity is on the ground and only "moves" downwards, it does not have a velocity.
+ return Double.compare(velocity.x, 0) != 0 || Double.compare(velocity.z, 0) != 0 || velocity.y > 0;
+ } else {
+ // The entity does not have velocity if the velocity is zero
+ return !velocity.equals(Vector3d.zero());
+ }
+ }
+
+ public void rotateHead(float yaw, float pitch) {
+ sendPacketToViewers(
+ new WrapperPlayServerEntityRotation(entityId, yaw, pitch, onGround)
+ );
+ }
+
+ public void rotateHead(Location location) {
+ rotateHead(location.getYaw(), location.getPitch());
+ }
+
+ public void rotateHead(WrapperEntity entity) {
+ rotateHead(entity.getLocation());
}
public void refresh() {
if (!spawned) return;
- sendPacketToViewers(meta.createPacket());
+ sendPacketToViewers(entityMeta.createPacket());
+ }
+
+ public void sendPacketToViewers(PacketWrapper> packet) {
+ viewers.forEach(uuid -> sendPacket(uuid, packet));
+ }
+
+ public void sendPacketsToViewers(PacketWrapper>... wrappers) {
+ for (PacketWrapper> wrapper : wrappers) {
+ sendPacketToViewers(wrapper);
+ }
+ }
+
+ private static void sendPacket(UUID user, PacketWrapper> wrapper) {
+
+ Object channel = EntityLib.getApi().getPacketEvents().getProtocolManager().getChannel(user);
+ if (channel == null) {
+ if (EntityLib.getApi().getSettings().isDebugMode()) {
+ EntityLib.getPlatform().getLogger().warning("Failed to send packet to " + user + " because the channel was null. They may be disconnected/not online.");
+ }
+ return;
+ }
+ EntityLib.getApi().getPacketEvents().getProtocolManager().sendPacket(channel, wrapper);
+ }
+
+ public boolean hasNoGravity() {
+ return entityMeta.hasNoGravity();
+ }
+
+ public void setHasNoGravity(boolean hasNoGravity) {
+ entityMeta.setHasNoGravity(hasNoGravity);
+ refresh();
}
/**
@@ -57,12 +344,25 @@ public class WrapperEntity implements Tickable {
}
passengers.add(passenger);
sendPacketToViewers(createPassengerPacket());
- WrapperEntity e = EntityLib.getEntity(passenger);
+ WrapperEntity e = EntityLib.getApi().getEntity(passenger);
if (e != null) {
e.riding = this.entityId;
+ e.preRidingLocation = e.location;
}
}
+ public @Nullable Location getPreRidingLocation() {
+ return preRidingLocation;
+ }
+
+ /**
+ * @return the entity id of the entity that the entity is riding, -1 if the entity is not riding
+ */
+ public int getRidingId() {
+ return riding;
+ }
+
+
/**
* Adds multiple passengers to the entity. The passengers will be visible to all viewers of the entity.
* @param passengers the entity ids of the passengers
@@ -101,10 +401,10 @@ public class WrapperEntity implements Tickable {
}
passengers.remove(passenger);
sendPacketToViewers(createPassengerPacket());
- WrapperEntity e = EntityLib.getEntity(passenger);
+ WrapperEntity e = EntityLib.getApi().getEntity(passenger);
if (e != null) {
e.riding = -1;
- e.teleport(e.getLocation());
+ e.teleport(e.preRidingLocation, e.onGround);
}
}
@@ -159,261 +459,28 @@ public class WrapperEntity implements Tickable {
return riding != -1;
}
- /**
- * Clears all passengers from the entity. The passengers will be removed from the view of all viewers of the entity.
- */
- public void clearPassengers() {
- if (passengers.isEmpty()) return;
- passengers.clear();
- sendPacketToViewers(createPassengerPacket());
+ public @NotNull Set getViewers() {
+ return Collections.unmodifiableSet(viewers);
}
- /**
- * @return the entity id of the entity that the entity is riding, -1 if the entity is not riding
- */
- public int getRidingId() {
- return riding;
- }
-
- protected WrapperPlayServerSetPassengers createPassengerPacket() {
- return new WrapperPlayServerSetPassengers(entityId, passengers.stream().mapToInt(i -> i).toArray());
- }
-
- public boolean spawn(Location location) {
- if (spawned) return false;
- this.location = location;
- this.spawned = true;
- int data = 0;
- Optional velocity;
- double veloX = 0, veloY = 0, veloZ = 0;
- if (meta instanceof ObjectData) {
- ObjectData od = (ObjectData) meta;
- data = od.getObjectData();
- if (od.requiresVelocityPacketAtSpawn()) {
- final WrapperPlayServerEntityVelocity veloPacket = getVelocityPacket();
- veloX = veloPacket.getVelocity().getX();
- veloY = veloPacket.getVelocity().getY();
- veloZ = veloPacket.getVelocity().getZ();
- }
- }
- if (veloX == 0 && veloY == 0 && veloZ == 0) {
- velocity = Optional.empty();
- } else {
- velocity = Optional.of(new Vector3d(veloX, veloY, veloZ));
- }
- sendPacketToViewers(
- new WrapperPlayServerSpawnEntity(
- entityId,
- this.uuid,
- entityType,
- location.getPosition(),
- location.getPitch(),
- location.getYaw(),
- location.getYaw(),
- data,
- velocity
- )
- );
- sendPacketToViewers(meta.createPacket());
- return true;
- }
-
- public boolean hasNoGravity() {
- return meta.isHasNoGravity();
- }
-
- public void setHasNoGravity(boolean hasNoGravity) {
- meta.setHasNoGravity(hasNoGravity);
- refresh();
- }
-
- public void rotateHead(float yaw, float pitch) {
- sendPacketToViewers(
- new WrapperPlayServerEntityRotation(entityId, yaw, pitch, onGround)
- );
- }
-
- public void rotateHead(Location location) {
- rotateHead(location.getYaw(), location.getPitch());
- }
-
- public void rotateHead(WrapperEntity entity) {
- rotateHead(entity.getLocation());
- }
-
- /**
- * Desyncs if the entity is riding some other entity. TODO: fix. This is a temporary solution.
- * @return the location of the entity
- */
public Location getLocation() {
- if (isRiding()) {
- WrapperEntity riding = EntityLib.getEntity(this.riding);
- assert riding != null;
- return riding.getLocation();
- }
-
- return new Location(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
- }
-
- public void remove() {
- if (!spawned) return;
- spawned = false;
- sendPacketToViewers(new WrapperPlayServerDestroyEntities(entityId));
- }
-
- public void teleport(Location location, boolean onGround) {
- this.location = location;
- this.onGround = onGround;
- sendPacketToViewers(
- new WrapperPlayServerEntityTeleport(entityId, location, onGround)
- );
- }
-
- public @NotNull Collection getViewers() {
- return Collections.unmodifiableCollection(viewers);
- }
-
- public void teleport(Location location) {
- teleport(location, true);
- }
-
- public void sendPacketToViewers(PacketWrapper> packet) {
- viewers.forEach(uuid -> EntityLib.sendPacket(uuid, packet));
- }
-
- public void sendPacketsToViewers(PacketWrapper>... wrappers) {
- for (PacketWrapper> wrapper : wrappers) {
- sendPacketToViewers(wrapper);
- }
- }
-
- public boolean addViewer(UUID uuid) {
- if (!viewers.add(uuid)) {
- return false;
- }
- if (!spawned) return false;
- WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(
- entityId,
- this.uuid,
- entityType,
- location.getPosition(),
- location.getPitch(),
- location.getYaw(),
- location.getYaw(),
- 0,
- Optional.empty()
- );
- EntityLib.sendPacket(uuid, packet);
- EntityLib.sendPacket(uuid, meta.createPacket());
- return true;
- }
-
- public void addViewer(User user) {
- addViewer(user.getUUID());
- }
-
- public void addViewerSilently(UUID viewer) {
- viewers.add(viewer);
- }
-
- public void addViewerSilently(User user) {
- viewers.add(user.getUUID());
- }
-
- public void removeViewerSilently(UUID uuid) {
- viewers.remove(uuid);
- }
-
- public void removeViewerSilently(User user) {
- viewers.remove(user.getUUID());
- }
-
- public void removeViewer(UUID uuid) {
- if (!viewers.remove(uuid)) {
- return;
- }
- EntityLib.sendPacket(uuid, new WrapperPlayServerDestroyEntities(entityId));
- }
-
- public EntityMeta getMeta() {
- return meta;
- }
-
- public UUID getUuid() {
- return uuid.get();
- }
-
- public EntityType getEntityType() {
- return entityType;
- }
-
- public int getEntityId() {
- return entityId;
- }
-
- public Class getMetaClass() {
- return EntityLib.getMetaClassOf(entityType);
- }
-
- public boolean hasSpawned() {
- return spawned;
- }
-
- public boolean hasVelocity() {
- if (isOnGround()) {
- // if the entity is on the ground and only "moves" downwards, it does not have a velocity.
- return Double.compare(velocity.x, 0) != 0 || Double.compare(velocity.z, 0) != 0 || velocity.y > 0;
- } else {
- // The entity does not have velocity if the velocity is zero
- return !velocity.equals(Vector3d.zero());
- }
- }
-
- public boolean isOnGround() {
- return onGround;
- }
-
- public Vector3d getVelocity() {
- return velocity;
- }
-
- public void setVelocity(Vector3d velocity) {
- this.velocity = velocity;
- sendPacketToViewers(getVelocityPacket());
- }
-
- public double getX() {
- return location.getX();
- }
-
- public double getY() {
- return location.getY();
- }
-
- public double getZ() {
- return location.getZ();
- }
-
- public float getYaw() {
- return location.getYaw();
- }
-
- public float getPitch() {
- return location.getPitch();
- }
-
- private WrapperPlayServerEntityVelocity getVelocityPacket() {
- Vector3d velocity = this.velocity.multiply(8000.0f / 20.0f);
- return new WrapperPlayServerEntityVelocity(entityId, velocity);
- }
-
- @Override
- public void update(long time) {
- tick(time);
+ return location;
}
@Override
public void tick(long time) {
-
+ if (isRiding()) {
+ WrapperEntity riding = getRiding();
+ if (riding != null) {
+ Location l = riding.getLocation();
+ location = new Location(
+ l.getX(),
+ l.getY() + 1,
+ l.getZ(),
+ l.getYaw(),
+ l.getPitch()
+ );
+ }
+ }
}
}
diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperEntityCreature.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityCreature.java
similarity index 79%
rename from src/main/java/me/tofaa/entitylib/entity/WrapperEntityCreature.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityCreature.java
index ba079d8..6771d15 100644
--- a/src/main/java/me/tofaa/entitylib/entity/WrapperEntityCreature.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityCreature.java
@@ -1,9 +1,8 @@
-package me.tofaa.entitylib.entity;
+package me.tofaa.entitylib.wrapper;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
-import me.tofaa.entitylib.entity.ai.AIGroup;
import me.tofaa.entitylib.meta.EntityMeta;
-import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.wrapper.ai.AIGroup;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
@@ -14,7 +13,6 @@ import java.util.UUID;
/**
* Represents a {@link WrapperEntity} with goals, AI and pathfinding.
*
- * To create a new {@link WrapperEntityCreature} use {@link EntityLib#createEntityCreature(int, UUID, EntityType)} or {@link EntityLib#createEntityCreature(UUID, EntityType)}.
*
* Creature entities require some sort of ticking mechanism on your server to work properly. They need to be dynamically updated every tick.
* Goal and Target selectors are grouped into AIGroups, which are then added to the entity. The AIGroups are then updated every tick.
@@ -32,14 +30,9 @@ public class WrapperEntityCreature extends WrapperLivingEntity {
}
@Override
- public void update(long time) {
- super.update(time);
- aiGroups.forEach(aiGroup -> aiGroup.update(time));
- }
-
- @Override
- public void kill() {
- super.kill();
+ public void tick(long time) {
+ super.tick(time);
+ aiGroups.forEach(aiGroup -> aiGroup.tick(time));
}
/**
diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperEntityEquipment.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityEquipment.java
similarity index 83%
rename from src/main/java/me/tofaa/entitylib/entity/WrapperEntityEquipment.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityEquipment.java
index e829114..9b2aa8f 100644
--- a/src/main/java/me/tofaa/entitylib/entity/WrapperEntityEquipment.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntityEquipment.java
@@ -1,4 +1,4 @@
-package me.tofaa.entitylib.entity;
+package me.tofaa.entitylib.wrapper;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
@@ -12,12 +12,14 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static me.tofaa.entitylib.extras.VersionChecker.verifyVersion;
+
public class WrapperEntityEquipment {
private static final EquipmentSlot[] EQUIPMENT_SLOTS = EquipmentSlot.values();
private final WrapperLivingEntity entity;
-
+ private boolean notifyChanges = true;
// 0 = main hand, 1 = offhand, 2 = boots, 3 = leggings, 4 = chestplate, 5 = helmet
private final ItemStack[] equipment = new ItemStack[6];
@@ -53,7 +55,7 @@ public class WrapperEntityEquipment {
}
public void setOffhand(@NotNull ItemStack itemStack) {
- EntityLib.verifyVersion(ServerVersion.V_1_9, "Offhand is only supported on 1.9+");
+ verifyVersion(ServerVersion.V_1_9, "Offhand is only supported on 1.9+");
equipment[1] = itemStack;
refresh();
}
@@ -92,7 +94,7 @@ public class WrapperEntityEquipment {
}
public @NotNull ItemStack getOffhand() {
- EntityLib.verifyVersion(ServerVersion.V_1_9, "Offhand is only supported on 1.9+");
+ verifyVersion(ServerVersion.V_1_9, "Offhand is only supported on 1.9+");
return getItem(EquipmentSlot.OFF_HAND);
}
@@ -111,7 +113,19 @@ public class WrapperEntityEquipment {
public void refresh() {
- this.entity.sendPacketToViewers(createPacket());
+ if (notifyChanges) {
+ this.entity.sendPacketToViewers(createPacket());
+ }
}
+ public boolean isNotifyingChanges() {
+ return notifyChanges;
+ }
+
+ public void setNotifyChanges(boolean notifyChanges) {
+ this.notifyChanges = notifyChanges;
+ if (notifyChanges) {
+ refresh();
+ }
+ }
}
diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperExperienceOrbEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java
similarity index 95%
rename from src/main/java/me/tofaa/entitylib/entity/WrapperExperienceOrbEntity.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java
index 8ee2ba1..27b38b8 100644
--- a/src/main/java/me/tofaa/entitylib/entity/WrapperExperienceOrbEntity.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java
@@ -1,4 +1,4 @@
-package me.tofaa.entitylib.entity;
+package me.tofaa.entitylib.wrapper;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.world.Location;
@@ -25,7 +25,9 @@ public class WrapperExperienceOrbEntity extends WrapperEntity {
* This is an attempt to mimmick the vanilla behavior.
*
*/
- public void updateSliding() {
+ @Override
+ public void tick(long time) {
+ super.tick(time);
if (hasNoGravity()) {
setVelocity(getVelocity().add(0, -0.3f, 0));
}
@@ -59,6 +61,8 @@ public class WrapperExperienceOrbEntity extends WrapperEntity {
return experience;
}
+
+
public void setExperience(short experience) {
getViewers().forEach(this::removeViewer);
this.experience = experience;
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperLivingEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperLivingEntity.java
new file mode 100644
index 0000000..835be99
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperLivingEntity.java
@@ -0,0 +1,16 @@
+package me.tofaa.entitylib.wrapper;
+
+import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import me.tofaa.entitylib.meta.EntityMeta;
+
+import java.util.UUID;
+
+public class WrapperLivingEntity extends WrapperEntity{
+
+
+
+
+ public WrapperLivingEntity(int entityId, UUID uuid, EntityType entityType, EntityMeta entityMeta) {
+ super(entityId, uuid, entityType, entityMeta);
+ }
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
new file mode 100644
index 0000000..7b35b3f
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
@@ -0,0 +1,84 @@
+package me.tofaa.entitylib.wrapper;
+
+import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import com.github.retrooper.packetevents.protocol.player.*;
+import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
+import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
+import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.meta.EntityMeta;
+import net.kyori.adventure.text.Component;
+
+import java.util.List;
+
+public class WrapperPlayer extends WrapperLivingEntity {
+
+ private final UserProfile profile;
+ private GameMode gameMode = GameMode.CREATIVE;
+ private Component displayName;
+
+
+ public WrapperPlayer(UserProfile profile, int entityId) {
+ super(entityId, profile.getUUID(), EntityTypes.PLAYER, EntityMeta.createMeta(entityId, EntityTypes.PLAYER));
+ this.profile = profile;
+ }
+
+
+ public void setGameMode(GameMode gameMode) {
+ this.gameMode = gameMode;
+ sendPacketsToViewers(new WrapperPlayServerPlayerInfo(
+ WrapperPlayServerPlayerInfo.Action.UPDATE_GAME_MODE,
+ new WrapperPlayServerPlayerInfo.PlayerData(displayName, profile, gameMode, null, -1)));
+ }
+
+ public void setDisplayName(Component displayName) {
+ this.displayName = displayName;
+ sendPacketsToViewers(new WrapperPlayServerPlayerInfo(
+ WrapperPlayServerPlayerInfo.Action.UPDATE_DISPLAY_NAME,
+ new WrapperPlayServerPlayerInfo.PlayerData(displayName, profile, gameMode, null, -1)));
+ }
+
+ public Component getDisplayName() {
+ return displayName;
+ }
+
+ public String getUsername() {
+ return profile.getName();
+ }
+
+ public List getTextureProperties() {
+ return profile.getTextureProperties();
+ }
+
+ public GameMode getGameMode() {
+ return gameMode;
+ }
+
+ @Override
+ public void addViewer(User user) {
+ super.addViewer(user);
+ user.sendPacket(createAddPacket());
+ }
+
+ @Override
+ public void removeViewer(User user) {
+ super.removeViewer(user);
+ user.sendPacket(createRemovePacket());
+ }
+
+ private WrapperPlayServerPlayerInfoUpdate createAddPacket() {
+ return new WrapperPlayServerPlayerInfoUpdate(
+ WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER,
+ new WrapperPlayServerPlayerInfoUpdate.PlayerInfo(
+ profile,
+ true, -1, gameMode, null, null
+ )
+ );
+ }
+
+ private WrapperPlayServerPlayerInfoRemove createRemovePacket() {
+ return new WrapperPlayServerPlayerInfoRemove(getUuid());
+ }
+
+}
diff --git a/src/main/java/me/tofaa/entitylib/entity/ai/AIGroup.java b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/AIGroup.java
similarity index 88%
rename from src/main/java/me/tofaa/entitylib/entity/ai/AIGroup.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/ai/AIGroup.java
index 8159247..6818b65 100644
--- a/src/main/java/me/tofaa/entitylib/entity/ai/AIGroup.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/AIGroup.java
@@ -1,6 +1,6 @@
-package me.tofaa.entitylib.entity.ai;
+package me.tofaa.entitylib.wrapper.ai;
-import me.tofaa.entitylib.Tickable;
+import me.tofaa.entitylib.tick.Tickable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -11,6 +11,7 @@ public class AIGroup implements Tickable {
private final List goalSelectors = new GoalSelectorList(this);
private GoalSelector currentGoalSelector;
+ private boolean ticking = true;
public @NotNull Collection getGoalSelectors() {
return goalSelectors;
@@ -37,7 +38,17 @@ public class AIGroup implements Tickable {
}
@Override
- public void update(long time) {
+ public boolean isTicking() {
+ return ticking;
+ }
+
+ @Override
+ public void setTicking(boolean ticking) {
+ this.ticking = ticking;
+ }
+
+ @Override
+ public void tick(long time) {
GoalSelector currentGoalSelector = getCurrentGoal();
if (currentGoalSelector != null && currentGoalSelector.shouldEnd()) {
@@ -64,12 +75,7 @@ public class AIGroup implements Tickable {
if (currentGoalSelector != null) {
currentGoalSelector.tick(time);
}
- tick(time);
}
- @Override
- public void tick(long time) {
-
- }
}
diff --git a/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelector.java b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/GoalSelector.java
similarity index 90%
rename from src/main/java/me/tofaa/entitylib/entity/ai/GoalSelector.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/ai/GoalSelector.java
index 37e7875..e6bbf3d 100644
--- a/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelector.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/GoalSelector.java
@@ -1,13 +1,13 @@
-package me.tofaa.entitylib.entity.ai;
+package me.tofaa.entitylib.wrapper.ai;
-import me.tofaa.entitylib.entity.WrapperEntityCreature;
+import me.tofaa.entitylib.wrapper.WrapperEntityCreature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
/**
- * Goals represent tasks that a {@link me.tofaa.entitylib.entity.WrapperEntityCreature} can perform.
+ * Goals represent tasks that a {@link me.tofaa.entitylib.wrapper.WrapperEntityCreature} can perform.
*/
public abstract class GoalSelector {
diff --git a/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelectorList.java b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/GoalSelectorList.java
similarity index 97%
rename from src/main/java/me/tofaa/entitylib/entity/ai/GoalSelectorList.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/ai/GoalSelectorList.java
index b783262..9971945 100644
--- a/src/main/java/me/tofaa/entitylib/entity/ai/GoalSelectorList.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/GoalSelectorList.java
@@ -1,4 +1,5 @@
-package me.tofaa.entitylib.entity.ai;
+package me.tofaa.entitylib.wrapper.ai;
+
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/main/java/me/tofaa/entitylib/entity/ai/goals/RandomHeadMovementGoal.java b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/goals/RandomHeadMovementGoal.java
similarity index 93%
rename from src/main/java/me/tofaa/entitylib/entity/ai/goals/RandomHeadMovementGoal.java
rename to api/src/main/java/me/tofaa/entitylib/wrapper/ai/goals/RandomHeadMovementGoal.java
index e085ace..4105d43 100644
--- a/src/main/java/me/tofaa/entitylib/entity/ai/goals/RandomHeadMovementGoal.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/ai/goals/RandomHeadMovementGoal.java
@@ -1,9 +1,9 @@
-package me.tofaa.entitylib.entity.ai.goals;
+package me.tofaa.entitylib.wrapper.ai.goals;
import com.github.retrooper.packetevents.util.Vector3d;
-import me.tofaa.entitylib.entity.WrapperEntityCreature;
-import me.tofaa.entitylib.entity.ai.GoalSelector;
import me.tofaa.entitylib.extras.CoordinateUtil;
+import me.tofaa.entitylib.wrapper.WrapperEntityCreature;
+import me.tofaa.entitylib.wrapper.ai.GoalSelector;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
@@ -66,7 +66,7 @@ public class RandomHeadMovementGoal extends GoalSelector {
@Override
public void tick(long time) {
--lookTime;
- entity.teleport(CoordinateUtil.withDirection(entity.getLocation(), lookDirection));
+ entity.teleport(CoordinateUtil.withDirection(entity.getLocation(), lookDirection), entity.isOnGround());
}
@Override
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
new file mode 100644
index 0000000..0e05cd4
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java
@@ -0,0 +1,65 @@
+package me.tofaa.entitylib.wrapper.hologram;
+
+import com.github.retrooper.packetevents.protocol.world.Location;
+import me.tofaa.entitylib.meta.display.TextDisplayMeta;
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+public interface Hologram {
+
+ static Hologram.@NotNull Legacy legacy(@NotNull Location location) {
+ return new LegacyHologram<>(location);
+ }
+
+ static Hologram.@NotNull Legacy legacy(@NotNull Location location, List lines) {
+ return new LegacyHologram<>(location, lines);
+ }
+
+ @NotNull Location getLocation();
+
+
+ void show();
+
+ void hide();
+
+ void teleport(Location location);
+
+ @Nullable Component getLine(int index);
+
+ int length();
+
+ void setLine(int index, @Nullable Component line);
+
+ void addLine(@Nullable Component line);
+
+ interface Modern extends Hologram {
+
+ // I got too lazy
+ void setModifier(@NotNull Consumer consumer);
+
+ }
+ interface Legacy extends Hologram {
+
+ float getLineOffset(boolean marker);
+
+ void setLineOffset(boolean marker, float value);
+
+ default float getLineOffset() {
+ return getLineOffset(false);
+ }
+
+ default void setLineOffset(float value) {
+ setLineOffset(false, value);
+ }
+
+ boolean isMarker();
+
+ void setMarker(boolean marker);
+
+ }
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java
new file mode 100644
index 0000000..c501a3d
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/LegacyHologram.java
@@ -0,0 +1,132 @@
+package me.tofaa.entitylib.wrapper.hologram;
+
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import com.github.retrooper.packetevents.protocol.world.Location;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.meta.other.ArmorStandMeta;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+final class LegacyHologram implements Hologram.Legacy {
+
+ private Location location;
+ private List lines = new ArrayList<>(3);
+ private float lineOffset = -0.9875f;
+ private float markerOffset = -0.40625f;
+ private boolean marker;
+
+ LegacyHologram(@NotNull Location location) {
+ this.location = location;
+ }
+
+ LegacyHologram(@NotNull Location location, List lines) {
+ this(location);
+ for (Component line : lines) {
+ addLine(line);
+ }
+ }
+
+ @Override
+ public boolean isMarker() {
+ return marker;
+ }
+
+ @Override
+ public void setMarker(boolean marker) {
+ this.marker = true;
+ if (lines.isEmpty()) return;
+ teleport(location); // refresh
+ }
+
+ @Override
+ public void show() {
+ for (WrapperEntity line : lines) {
+ line.spawn(location);
+ }
+ teleport(location);
+ }
+
+ @Override
+ public void hide() {
+ for (WrapperEntity line : lines) {
+ line.despawn();
+ }
+ }
+
+ @Override
+ public void teleport(Location location) {
+ this.location = location;
+ // reversed order
+ for (int i = lines.size() - 1; i >= 0; i--) {
+ WrapperEntity line = lines.get(i);
+ double y;
+ if (marker) {
+ y = location.getY() + markerOffset;
+ } else {
+ y = location.getY() + (i * lineOffset);
+ }
+ ArmorStandMeta meta = (ArmorStandMeta) line.getEntityMeta();
+ meta.setMarker(marker);
+ Location l = new Location(location.getX(), y, location.getZ(), location.getYaw(), location.getPitch());
+ line.teleport(l, false);
+ }
+ }
+
+ @Override
+ public @Nullable Component getLine(int index) {
+ if (index < 0 || index >= lines.size()) {
+ return null;
+ }
+ return lines.get(index).getEntityMeta().getCustomName();
+ }
+
+ @Override
+ public void setLine(int index, @Nullable Component line) {
+ WrapperEntity e = EntityLib.getApi().spawnEntity(EntityTypes.ARMOR_STAND, location);
+ ArmorStandMeta meta = (ArmorStandMeta) e.getEntityMeta();
+ meta.setCustomName(line);
+ meta.setCustomNameVisible(true);
+ meta.setInvisible(true);
+ meta.setHasNoGravity(true);
+ meta.setSmall(true);
+ meta.setMarker(marker);
+ this.lines.set(index, e);
+ e.spawn(location);
+ teleport(location);
+ }
+
+ @Override
+ public void addLine(@Nullable Component line) {
+ setLine(lines.size(), line);
+ }
+
+ @Override
+ public float getLineOffset(boolean marker) {
+ return marker ? markerOffset : lineOffset;
+ }
+
+ @Override
+ public int length() {
+ return lines.size();
+ }
+
+ @Override
+ public void setLineOffset(boolean marker, float value) {
+ if (marker) {
+ markerOffset = value;
+ } else {
+ lineOffset = value;
+ }
+ }
+
+ @Override
+ public @NotNull Location getLocation() {
+ return location;
+ }
+
+}
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java
new file mode 100644
index 0000000..5c35552
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/ModernHologram.java
@@ -0,0 +1,91 @@
+package me.tofaa.entitylib.wrapper.hologram;
+
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import com.github.retrooper.packetevents.protocol.world.Location;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.meta.display.TextDisplayMeta;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+final class ModernHologram implements Hologram.Modern {
+
+ private Location location;
+ private List lines = new ArrayList<>(3);
+ private Consumer modifier;
+
+ @Override
+ public void show() {
+ for (WrapperEntity line : lines) {
+ line.spawn(location);
+ }
+ teleport(location);
+ }
+
+ @Override
+ public void hide() {
+ for (WrapperEntity line : lines) {
+ line.despawn();
+ }
+ }
+
+ @Override
+ public void teleport(Location location) {
+ this.location = location;
+ if (lines.isEmpty()) return;
+ WrapperEntity first = lines.get(0);
+ first.teleport(location);
+ for (WrapperEntity e : lines) {
+ if (e.getUuid().equals(first.getUuid())) continue;
+ first.addPassenger(e);
+ }
+ }
+
+ @Override
+ public @Nullable Component getLine(int index) {
+ if (index < 0 || index >= lines.size()) {
+ return null;
+ }
+ return lines.get(index).getEntityMeta().getCustomName();
+ }
+
+ @Override
+ public void setLine(int index, @Nullable Component line) {
+ WrapperEntity e = EntityLib.getApi().spawnEntity(EntityTypes.TEXT_DISPLAY, location);
+ TextDisplayMeta meta = (TextDisplayMeta) e.getEntityMeta();
+ meta.setInvisible(true);
+ meta.setHasNoGravity(true);
+ meta.setText(line);
+ this.modifier.accept(meta);
+ this.lines.set(index, e);
+ e.spawn(location);
+ teleport(location);
+ }
+
+ @Override
+ public void addLine(@Nullable Component line) {
+ setLine(lines.size(), line);
+ }
+
+
+ @Override
+ public int length() {
+ return lines.size();
+ }
+
+ @Override
+ public @NotNull Location getLocation() {
+ return location;
+ }
+
+
+ @Override
+ public void setModifier(@NotNull Consumer consumer) {
+ this.modifier = consumer;
+ }
+}
diff --git a/build.gradle b/build.gradle
index 1958f2c..555b4ab 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,6 +5,12 @@ plugins {
allprojects {
+ project.ext.adventureVersion = '4.15.0'
+ project.ext.adventureDependencies=["net.kyori:adventure-api:${adventureVersion}",
+ "net.kyori:adventure-text-serializer-gson:${adventureVersion}",
+ "net.kyori:adventure-text-serializer-legacy:${adventureVersion}",
+ "net.kyori:adventure-nbt:${adventureVersion}"]
+
apply plugin: 'java'
group = 'me.tofaa.entitylib'
diff --git a/code-gen/build.gradle b/code-gen/build.gradle
new file mode 100644
index 0000000..e6439d3
--- /dev/null
+++ b/code-gen/build.gradle
@@ -0,0 +1,20 @@
+plugins {
+ id 'java'
+}
+
+
+// jdk 17
+sourceCompatibility = JavaVersion.VERSION_17
+targetCompatibility = JavaVersion.VERSION_17
+
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'com.google.code.gson:gson:2.10.1'
+ implementation 'com.squareup:javapoet:1.13.0'
+ implementation 'com.github.retrooper.packetevents:api:2.2.0'
+ implementation 'org.jetbrains:annotations:24.0.0'
+}
diff --git a/code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java b/code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java
new file mode 100644
index 0000000..def0633
--- /dev/null
+++ b/code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java
@@ -0,0 +1,83 @@
+package me.tofaa.entitylib.codegen;
+
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.squareup.javapoet.*;
+import org.jetbrains.annotations.ApiStatus;
+
+import javax.lang.model.element.Modifier;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public final class Main {
+
+ private Main() {}
+ private static final File OUT = new File("./api/src/main/java");
+ static {
+ if (!OUT.exists()) {
+ OUT.mkdirs();
+ }
+ if (!OUT.isDirectory()) {
+ OUT.delete();
+ OUT.mkdirs();
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+
+ TypeSpec.Builder baseBuilder = TypeSpec.classBuilder(ClassName.get("me.tofaa.entitylib.meta", "MetaOffsetConverter"))
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+ .addAnnotation(ApiStatus.Internal.class)
+ .addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "unused").build())
+ .addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).build());
+
+ Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create();
+ InputStream stream = Main.class.getResourceAsStream("/offset-calculator.json");
+ if (stream == null) {
+ throw new RuntimeException("offset-calculator.json not found");
+ }
+ InputStreamReader reader = new InputStreamReader(stream);
+ TypeHolder[] types = gson.fromJson(reader, TypeHolder[].class);
+ for (TypeHolder type : types) {
+ System.out.println("Generating type" + type.className());
+
+ TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(type.className() + "Offsets")
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC)
+ .addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).build());
+
+ for (MetaOffset offset : type.offsets()) {
+
+ MethodSpec.Builder method = MethodSpec.methodBuilder(offset.name() + "Offset")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(byte.class);
+
+ String version = "int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion()";
+ method.addStatement(version);
+ for (VersionCheck check : offset.checks()) {
+ method.beginControlFlow("if (protocolVersion >= $L && protocolVersion <= $L)", check.to(), check.from());
+ method.addStatement("return $L", check.offset());
+ method.endControlFlow();
+ }
+ method.addStatement("throw new RuntimeException(\"Unknown protocol version for this method\")");
+ typeBuilder.addMethod(method.build());
+ }
+ baseBuilder.addType(typeBuilder.build());
+ }
+
+
+ TypeSpec base = baseBuilder.build();
+ System.out.println("Writing to file");
+ JavaFile file = JavaFile.builder("me.tofaa.entitylib.meta", base)
+ .addStaticImport(ClassName.get("me.tofaa.entitylib", "EntityLib"), "getApi")
+ .addFileComment("This class is generated by code-gen module. Do not edit manually.\n")
+ .indent(" ")
+ .skipJavaLangImports(true)
+ .build();
+ file.writeTo(OUT);
+ }
+
+
+}
diff --git a/code-gen/src/main/java/me/tofaa/entitylib/codegen/MetaOffset.java b/code-gen/src/main/java/me/tofaa/entitylib/codegen/MetaOffset.java
new file mode 100644
index 0000000..5cb106f
--- /dev/null
+++ b/code-gen/src/main/java/me/tofaa/entitylib/codegen/MetaOffset.java
@@ -0,0 +1,4 @@
+package me.tofaa.entitylib.codegen;
+
+public record MetaOffset(String name, VersionCheck[] checks) {
+}
diff --git a/code-gen/src/main/java/me/tofaa/entitylib/codegen/TypeHolder.java b/code-gen/src/main/java/me/tofaa/entitylib/codegen/TypeHolder.java
new file mode 100644
index 0000000..7391f9f
--- /dev/null
+++ b/code-gen/src/main/java/me/tofaa/entitylib/codegen/TypeHolder.java
@@ -0,0 +1,4 @@
+package me.tofaa.entitylib.codegen;
+
+public record TypeHolder(String className, MetaOffset[] offsets) {
+}
diff --git a/code-gen/src/main/java/me/tofaa/entitylib/codegen/VersionCheck.java b/code-gen/src/main/java/me/tofaa/entitylib/codegen/VersionCheck.java
new file mode 100644
index 0000000..1120db8
--- /dev/null
+++ b/code-gen/src/main/java/me/tofaa/entitylib/codegen/VersionCheck.java
@@ -0,0 +1,4 @@
+package me.tofaa.entitylib.codegen;
+
+public record VersionCheck(int from, int to, byte offset) {
+}
diff --git a/code-gen/src/main/resources/offset-calculator.json b/code-gen/src/main/resources/offset-calculator.json
new file mode 100644
index 0000000..079092b
--- /dev/null
+++ b/code-gen/src/main/resources/offset-calculator.json
@@ -0,0 +1,581 @@
+[
+ {
+ "class-name": "EntityMeta",
+ "offsets": [
+ {
+ "name": "airTicks",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 1
+ }
+ ]
+ },
+ {
+ "name": "customName",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 2
+ }
+ ]
+ },
+ {
+ "name": "customNameVisible",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 3
+ }
+ ]
+ },
+ {
+ "name": "silent",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 4
+ }
+ ]
+ },
+ {
+ "name": "hasNoGravity",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 5
+ }
+ ]
+ },
+ {
+ "name": "pose",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 6
+ }
+ ]
+ },
+ {
+ "name": "ticksFrozenInPowderedSnow",
+ "checks": [
+ {
+ "from": 765,
+ "to": 47,
+ "offset": 7
+ }
+ ]
+ }
+ ]
+ },
+
+
+
+ {
+ "class-name": "AbstractDisplayMeta",
+ "offsets": [
+ {
+ "name": "interpolationDelay",
+ "checks": [
+ {
+ "from": 765,
+ "to": 762,
+ "offset": 8
+ }
+ ]
+ },
+ {
+ "name": "transformationDuration",
+ "checks": [
+ {
+ "from": 765,
+ "to": 762,
+ "offset": 9
+ }
+ ]
+ },
+ {
+ "name": "positionRotationInterpolationDuration",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 10
+ }
+ ]
+ },
+ {
+ "name": "translation",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 11
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 10
+ }
+ ]
+ },
+ {
+ "name": "scale",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 12
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 11
+ }
+ ]
+ },
+ {
+ "name": "leftRotation",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 13
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 12
+ }
+ ]
+ },
+ {
+ "name": "rightRotation",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 14
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 13
+ }
+ ]
+ },
+ {
+ "name": "billboardConstraints",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 15
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 14
+ }
+ ]
+ },
+ {
+ "name": "brightnessOverride",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 16
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 15
+ }
+ ]
+ },
+ {
+ "name": "viewRange",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 17
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 16
+ }
+ ]
+ },
+ {
+ "name": "shadowRadius",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 18
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 17
+ }
+ ]
+ },
+ {
+ "name": "shadowStrength",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 19
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 18
+ }
+ ]
+ },
+ {
+ "name": "width",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 20
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 19
+ }
+ ]
+ },
+ {
+ "name": "height",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 21
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 20
+ }
+ ]
+ },
+ {
+ "name": "glowColorOverride",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 22
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 21
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "class-name": "BlockDisplayMeta",
+ "offsets": [
+ {
+ "name": "blockId",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 23
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 22
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "class-name": "ItemDisplayMeta",
+ "offsets": [
+ {
+ "name": "item",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 24
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 23
+ }
+ ]
+ },
+ {
+ "name": "displayType",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 25
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 24
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "class-name": "TextDisplayMeta",
+ "offsets": [
+ {
+ "name": "text",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 26
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 25
+ }
+ ]
+ },
+ {
+ "name": "textColor",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 27
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 26
+ }
+ ]
+ },
+ {
+ "name": "textBackgroundColor",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 28
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 27
+ }
+ ]
+ },
+ {
+ "name": "textBackground",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 29
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 28
+ }
+ ]
+ },
+ {
+ "name": "textScale",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 30
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 29
+ }
+ ]
+ },
+ {
+ "name": "textAlignment",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 31
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 30
+ }
+ ]
+ },
+ {
+ "name": "lineWidth",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 32
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 31
+ }
+ ]
+ },
+ {
+ "name": "backgroundColor",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 33
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 32
+ }
+ ]
+ },
+ {
+ "name": "textOpacity",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 34
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 33
+ }
+ ]
+ },
+ {
+ "name": "shadow",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 35
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 34
+ }
+ ]
+ },
+ {
+ "name": "seeThrough",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 36
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 35
+ }
+ ]
+ },
+ {
+ "name": "useDefaultBackground",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 37
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 36
+ }
+ ]
+ },
+ {
+ "name": "allighnLeft",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 38
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 37
+ }
+ ]
+ },
+ {
+ "name": "allighnRight",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 39
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 38
+ }
+ ]
+ },
+ {
+ "name": "allighnCenter",
+ "checks": [
+ {
+ "from": 765,
+ "to": 764,
+ "offset": 40
+ },
+ {
+ "from": 763,
+ "to": 762,
+ "offset": 39
+ }
+ ]
+ }
+ ]
+
+ }
+]
\ No newline at end of file
diff --git a/common/build.gradle b/common/build.gradle
new file mode 100644
index 0000000..4cb63f2
--- /dev/null
+++ b/common/build.gradle
@@ -0,0 +1,15 @@
+plugins {
+ id 'java'
+ id 'java-library'
+}
+
+group = 'org.example'
+version = '1.0-SNAPSHOT'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ api(project(":api"))
+}
diff --git a/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java b/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java
new file mode 100644
index 0000000..d6ab72d
--- /dev/null
+++ b/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java
@@ -0,0 +1,136 @@
+package me.tofaa.entitylib.common;
+
+import com.github.retrooper.packetevents.PacketEventsAPI;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import com.github.retrooper.packetevents.protocol.player.UserProfile;
+import com.github.retrooper.packetevents.protocol.world.Location;
+import me.tofaa.entitylib.APIConfig;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.EntityLibAPI;
+import me.tofaa.entitylib.Platform;
+import me.tofaa.entitylib.meta.EntityMeta;
+import me.tofaa.entitylib.meta.projectile.ThrownExpBottleMeta;
+import me.tofaa.entitylib.meta.types.LivingEntityMeta;
+import me.tofaa.entitylib.tick.TickContainer;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+import me.tofaa.entitylib.wrapper.WrapperExperienceOrbEntity;
+import me.tofaa.entitylib.wrapper.WrapperLivingEntity;
+import me.tofaa.entitylib.wrapper.WrapperPlayer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+public abstract class AbstractEntityLibAPI implements EntityLibAPI {
+
+ protected final Platform platform;
+ protected final PacketEventsAPI> packetEvents;
+ protected final APIConfig settings;
+ protected final Collection> tickContainers;
+ protected final Map globalEntityMap = new ConcurrentHashMap<>();
+ protected final Map entitiesById = new ConcurrentHashMap<>();
+ protected final Map entities = new ConcurrentHashMap<>();
+
+ protected AbstractEntityLibAPI(Platform platform, APIConfig settings) {
+ this.platform = platform;
+ this.packetEvents = settings.getPacketEvents();
+ this.settings = settings;
+ this.tickContainers = settings.shouldTickTickables() ? new HashSet<>() : Collections.emptyList();
+ }
+
+
+ @Override
+ public @NotNull WrapperPlayer spawnPlayer(UserProfile profile, Location location) {
+ if (getEntity(profile.getUUID()) != null) {
+ throw new IllegalArgumentException("Entity with UUID " + profile.getUUID() + " already exists in this world.");
+ }
+
+ int id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
+ while (entitiesById.containsKey(id)) {
+ id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
+ }
+ WrapperPlayer player = new WrapperPlayer(profile, id);
+ player.spawn(location);
+ entities.put(player.getUuid(), player);
+ entitiesById.put(player.getEntityId(), player);
+ return player;
+ }
+
+ @Override
+ public @NotNull T1 spawnEntity(@NotNull T1 entity, @NotNull Location location) {
+ entity.spawn(location);
+ entities.put(entity.getUuid(), entity);
+ entitiesById.put(entity.getEntityId(), entity);
+ return entity;
+ }
+
+ @Override
+ public void removeEntity(WrapperEntity entity) {
+ entity.despawn();
+ this.entities.remove(entity.getUuid());
+ this.entitiesById.remove(entity.getEntityId());
+ }
+
+ @Override
+ public @NotNull T1 spawnEntity(@NotNull Class wrapperClass, @NotNull EntityType entityType, @NotNull Location location) {
+ UUID uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(entityType);
+ while (entities.containsKey(uuid)) {
+ uuid = EntityLib.getPlatform().getEntityUuidProvider().provide(entityType);
+ }
+ int entityId = EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType);
+ while (entitiesById.containsKey(entityId)) {
+ entityId = EntityLib.getPlatform().getEntityIdProvider().provide(uuid, entityType);
+ }
+ EntityMeta meta = EntityMeta.createMeta(entityId, entityType);
+ WrapperEntity e;
+ if (meta instanceof LivingEntityMeta) {
+ e = new WrapperLivingEntity(entityId, uuid, entityType, meta);
+ }
+ else if (meta instanceof ThrownExpBottleMeta) {
+ e = new WrapperExperienceOrbEntity(entityId, uuid, entityType, meta);
+ }
+ else {
+ e = new WrapperEntity(entityId, uuid, entityType, meta);
+ }
+ return spawnEntity(wrapperClass.cast(e), location);
+ }
+
+ @Override
+ public @NotNull WrapperEntity spawnEntity(@NotNull EntityType entityType, @NotNull Location location) {
+ return spawnEntity(WrapperEntity.class, entityType, location);
+ }
+
+ @Override
+ public @Nullable WrapperEntity getEntity(int id) {
+ return entitiesById.get(id);
+ }
+
+ @Override
+ public @Nullable WrapperEntity getEntity(@NotNull UUID uuid) {
+ return entities.get(uuid);
+ }
+
+ @Override
+ public @NotNull Collection getAllEntities() {
+ return Collections.unmodifiableCollection(entities.values());
+ }
+
+ @NotNull
+ @Override
+ public APIConfig getSettings() {
+ return settings;
+ }
+
+ @Override
+ public PacketEventsAPI> getPacketEvents() {
+ return packetEvents;
+ }
+
+ @NotNull
+ @Override
+ public Collection> getTickContainers() {
+ return tickContainers;
+ }
+}
diff --git a/common/src/main/java/me/tofaa/entitylib/common/AbstractPlatform.java b/common/src/main/java/me/tofaa/entitylib/common/AbstractPlatform.java
new file mode 100644
index 0000000..a2700e1
--- /dev/null
+++ b/common/src/main/java/me/tofaa/entitylib/common/AbstractPlatform.java
@@ -0,0 +1,76 @@
+package me.tofaa.entitylib.common;
+
+import me.tofaa.entitylib.APIConfig;
+import me.tofaa.entitylib.EntityIdProvider;
+import me.tofaa.entitylib.EntityUuidProvider;
+import me.tofaa.entitylib.Platform;
+import me.tofaa.entitylib.event.EventBus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.logging.Logger;
+
+public abstract class AbstractPlatform implements Platform
{
+
+
+ protected final P handle;
+ protected Logger logger;
+ private EventBus eventBus;
+ private EntityIdProvider entityIdProvider;
+ private EntityUuidProvider entityUuidProvider;
+
+ public AbstractPlatform(P handle) {
+ this.handle = handle;
+ this.entityIdProvider = new EntityIdProvider.DefaultEntityIdProvider();
+ this.entityUuidProvider = new EntityUuidProvider.DefaultEntityUuidProvider();
+ }
+
+
+ @Override
+ public void setupApi(@NotNull APIConfig settings) {
+ this.eventBus = EventBus.newBus(settings.shouldUseAsyncEvents());
+ this.entityIdProvider = new EntityIdProvider.DefaultEntityIdProvider();
+ this.entityUuidProvider = new EntityUuidProvider.DefaultEntityUuidProvider();
+
+
+ }
+
+ @NotNull
+ @Override
+ public Logger getLogger() {
+ return logger;
+ }
+
+ @NotNull
+ @Override
+ public EntityIdProvider getEntityIdProvider() {
+ return entityIdProvider;
+ }
+
+ @NotNull
+ @Override
+ public EntityUuidProvider getEntityUuidProvider() {
+ return entityUuidProvider;
+ }
+
+ @Override
+ public void setEntityIdProvider(EntityIdProvider entityIdProvider) {
+ this.entityIdProvider = entityIdProvider;
+ }
+
+ @Override
+ public void setEntityUuidProvider(EntityUuidProvider entityUuidProvider) {
+ this.entityUuidProvider = entityUuidProvider;
+ }
+
+ @NotNull
+ @Override
+ public EventBus getEventBus() {
+ return eventBus;
+ }
+
+ @NotNull
+ @Override
+ public P getHandle() {
+ return handle;
+ }
+}
diff --git a/platforms/spigot/build.gradle b/platforms/spigot/build.gradle
new file mode 100644
index 0000000..f74503b
--- /dev/null
+++ b/platforms/spigot/build.gradle
@@ -0,0 +1,17 @@
+plugins {
+ id 'java'
+ id 'java-library'
+}
+
+group = 'me.tofaa.entitylib'
+version = '1.0-SNAPSHOT'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ api(project(":common"))
+ compileOnly('com.github.retrooper.packetevents:spigot:2.0.2')
+ compileOnly('org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT')
+}
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..6f9eaf9
--- /dev/null
+++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java
@@ -0,0 +1,39 @@
+package me.tofaa.entitylib.spigot;
+
+import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
+import com.github.retrooper.packetevents.protocol.player.HumanoidArm;
+import com.github.retrooper.packetevents.protocol.player.TextureProperty;
+import com.github.retrooper.packetevents.protocol.player.UserProfile;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Pose;
+import org.bukkit.inventory.MainHand;
+import org.bukkit.profile.PlayerProfile;
+import org.bukkit.profile.PlayerTextures;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+public final class ExtraConversionUtil {
+
+ private ExtraConversionUtil() {
+
+ }
+
+ public static UserProfile fromBukkitPlayerProfile(PlayerProfile player) {
+ UUID uuid = player.getUniqueId();
+ String name = player.getName();
+ // TODO: Textures
+ return new UserProfile(uuid, name, Collections.emptyList());
+ }
+
+ 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/SpigotEntityLibAPI.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibAPI.java
new file mode 100644
index 0000000..f32b86c
--- /dev/null
+++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibAPI.java
@@ -0,0 +1,111 @@
+package me.tofaa.entitylib.spigot;
+
+import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import com.github.retrooper.packetevents.protocol.world.Location;
+import io.github.retrooper.packetevents.util.SpigotConversionUtil;
+import me.tofaa.entitylib.APIConfig;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.common.AbstractEntityLibAPI;
+import me.tofaa.entitylib.meta.EntityMeta;
+import me.tofaa.entitylib.meta.types.LivingEntityMeta;
+import me.tofaa.entitylib.meta.types.PlayerMeta;
+import me.tofaa.entitylib.tick.TickContainer;
+import me.tofaa.entitylib.utils.Check;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+import me.tofaa.entitylib.wrapper.WrapperLivingEntity;
+import me.tofaa.entitylib.wrapper.WrapperPlayer;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitTask;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.UUID;
+import java.util.logging.Level;
+
+public class SpigotEntityLibAPI extends AbstractEntityLibAPI {
+
+
+ SpigotEntityLibAPI(SpigotEntityLibPlatform platform, APIConfig settings) {
+ super(platform, settings);
+ }
+
+ @Override
+ public void onLoad() {
+ }
+
+ @Override
+ public void onEnable() {
+
+ }
+
+ @Override
+ public @NotNull T cloneEntity(@NotNull Object platformEntity, @NotNull Location location) {
+ Check.stateCondition(!(platformEntity instanceof Entity), "Entity must be a Bukkit entity");
+ Entity e = (Entity) platformEntity;
+ EntityType type = SpigotConversionUtil.fromBukkitEntityType(e.getType());
+ EntityMeta meta = EntityMeta.createMeta(e.getEntityId(), type);
+ 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()));
+ }
+ WrapperEntity entity;
+ int id = EntityLib.getPlatform().getEntityIdProvider().provide(e.getUniqueId(), type);
+ UUID uuid = e.getUniqueId();
+ if (meta instanceof PlayerMeta) {
+ Player p = (Player) e;
+ entity = new WrapperPlayer(ExtraConversionUtil.fromBukkitPlayerProfile(p.getPlayerProfile()), id);
+ }
+ else if (meta instanceof LivingEntityMeta) {
+ entity = new WrapperLivingEntity(id, uuid, type, meta);
+ }
+ else {
+ entity = new WrapperEntity(id, uuid, type, meta);
+ }
+ if (entity == null) {
+ throw new IllegalArgumentException("Could not clone entity");
+ }
+ return (T) this.spawnEntity(entity, location);
+ }
+
+ @Override
+ public void addTickContainer(@NotNull TickContainer, BukkitTask> tickContainer) {
+ if (!settings.shouldTickTickables()) {
+ if (settings.isDebugMode()) {
+ platform.getLogger().log(Level.WARNING, "Tried to add a TickContainer when ticking tickables is disabled!");
+ }
+ return;
+ }
+ tickContainers.add(tickContainer);
+ if (settings.isDebugMode()) {
+ platform.getLogger().log(Level.CONFIG, "Registering new tick container...");
+ }
+ getTickContainers().add(tickContainer);
+ BukkitTask task = Bukkit.getScheduler().runTaskTimerAsynchronously(platform.getHandle(), () -> tickContainer.tick(System.currentTimeMillis()), 1L, 1L);
+ tickContainer.setHandle(task);
+ }
+
+
+
+}
diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java
new file mode 100644
index 0000000..fd509b0
--- /dev/null
+++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java
@@ -0,0 +1,36 @@
+package me.tofaa.entitylib.spigot;
+
+import me.tofaa.entitylib.APIConfig;
+import me.tofaa.entitylib.EntityLibAPI;
+import me.tofaa.entitylib.common.AbstractPlatform;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.NotNull;
+import java.util.logging.Logger;
+
+public class SpigotEntityLibPlatform extends AbstractPlatform {
+
+ private SpigotEntityLibAPI api;
+ public SpigotEntityLibPlatform(@NotNull JavaPlugin plugin) {
+ super(plugin);
+ }
+
+ @Override
+ public void setupApi(@NotNull APIConfig settings) {
+ super.setupApi(settings);
+ this.logger = settings.shouldUsePlatformLogger() ? handle.getLogger() : Logger.getLogger("EntityLib");
+ this.api = new SpigotEntityLibAPI(this, settings);
+ this.api.onLoad();
+ this.api.onEnable();
+ }
+
+
+ @Override
+ public SpigotEntityLibAPI getAPI() {
+ return api;
+ }
+
+ @Override
+ public String getName() {
+ return "Spigot";
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index a756887..6b9d5fb 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,8 @@
rootProject.name = 'EntityLib'
include 'test-plugin'
+include 'api'
+include 'platforms:spigot'
+findProject(':platforms:spigot')?.name = 'spigot'
+include 'common'
+include 'code-gen'
diff --git a/src/.gitignore b/src/.gitignore
deleted file mode 100644
index b63da45..0000000
--- a/src/.gitignore
+++ /dev/null
@@ -1,42 +0,0 @@
-.gradle
-build/
-!gradle/wrapper/gradle-wrapper.jar
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### IntelliJ IDEA ###
-.idea/modules.xml
-.idea/jarRepositories.xml
-.idea/compiler.xml
-.idea/libraries/
-*.iws
-*.iml
-*.ipr
-out/
-!**/src/main/**/out/
-!**/src/test/**/out/
-
-### Eclipse ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-bin/
-!**/src/main/**/bin/
-!**/src/test/**/bin/
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-
-### VS Code ###
-.vscode/
-
-### Mac OS ###
-.DS_Store
\ No newline at end of file
diff --git a/src/main/java/me/tofaa/entitylib/EntityLib.java b/src/main/java/me/tofaa/entitylib/EntityLib.java
deleted file mode 100644
index d8f9ebf..0000000
--- a/src/main/java/me/tofaa/entitylib/EntityLib.java
+++ /dev/null
@@ -1,346 +0,0 @@
-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.entity.type.EntityTypes;
-import com.github.retrooper.packetevents.protocol.packettype.PacketType;
-import com.github.retrooper.packetevents.protocol.player.InteractionHand;
-import com.github.retrooper.packetevents.protocol.player.User;
-import com.github.retrooper.packetevents.wrapper.PacketWrapper;
-import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
-import me.tofaa.entitylib.entity.*;
-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.ApiStatus;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiFunction;
-
-/**
- * Base API class for EntityLib, contains all the methods to interact with the library.
- *
- * Initialization should be done before PacketEvents. After PE is initialized, call {@link EntityLib#init(PacketEventsAPI)} to initialize EntityLib.
- *
- * To enable entity interactions, call {@link EntityLib#enableEntityInteractions()}. these will help you interact with a {@link WrapperEntity} object.
- *
- * By default, EntityLib does not persistently store data, this is planned for a future feature but for now you must store your own data if you want it to persist after restart.
- *
- */
-public final class EntityLib {
-
- private EntityLib() {}
- private static final HashMap metadata = new HashMap<>();
- private static final Map entities = new ConcurrentHashMap<>();
- private static final Map entitiesById = new ConcurrentHashMap<>();
- private static EntityInteractionProcessor interactionProcessor;
- private static boolean initialized = false;
- private static PacketEventsAPI> packetEvents;
- private static MetaConverterRegistry metaRegistry;
- private static EntityIdProvider entityIdProvider = EntityIdProvider.simple();
-
- /**
- * Initialize EntityLib.
- *
- * This method should be called after PacketEvents is initialized.
- * Loads the internal metadata converter registry and sets the library usable
- *
- * @param packetEvents PacketEventsAPI instance
- */
- public static void init(@NotNull PacketEventsAPI> packetEvents) {
- if (initialized) {
- throw new IllegalStateException("EntityLib is already initialized");
- }
- initialized = true;
- EntityLib.packetEvents = packetEvents;
- if (!packetEvents.isInitialized()) {
- initialized = false;
- throw new IllegalStateException("PacketEvents is not initialized");
- }
- metaRegistry = new MetaConverterRegistry();
- }
-
- /**
- * Enable entity interactions.
- *
- * Enables entity interactions to be handled by EntityLib, rather than the developer.
- *
- * This will register a PacketEvents listener for {@link PacketType.Play.Client#INTERACT_ENTITY} and call {@link EntityInteractionProcessor#process(WrapperEntity, WrapperPlayClientInteractEntity.InteractAction, InteractionHand, User)}.
- *
- * To set the interaction processor, call {@link EntityLib#setInteractionProcessor(EntityInteractionProcessor)}.
- *
- */
- public static void enableEntityInteractions() {
- checkInit();
- packetEvents.getEventManager().registerListener(new PacketListenerAbstract() {
- @Override
- public void onPacketReceive(PacketReceiveEvent event) {
- if (interactionProcessor == null) return;
- if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) return;
- WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
- WrapperEntity entity = getEntity(packet.getEntityId());
- if (entity == null) return;
- interactionProcessor.process(
- entity, packet.getAction(), packet.getHand(), event.getUser()
- );
- }
- });
- }
-
- /**
- * @param entityId the entity id
- * @return the entity with the given id, or null if an entity with that id does not exist
- */
- public static @Nullable WrapperEntity getEntity(int entityId) {
- checkInit();
- return entitiesById.get(entityId);
- }
-
- /**
- * Removes the entity completely from EntityLib and the platform.
- * The viewer will no longer be able to see the entity.
- */
- public static boolean removeEntity(int entityId) {
- checkInit();
- WrapperEntity e = entitiesById.get(entityId);
- if (e == null) return false;
- entities.remove(e.getUuid());
- entitiesById.remove(entityId);
- e.remove();
- return true;
- }
-
- /**
- * Removes the entity completely from EntityLib and the platform.
- * The viewer will no longer be able to see the entity.
- */
- public static boolean removeEntity(WrapperEntity entity) {
- return removeEntity(entity.getEntityId());
- }
-
- /**
- * @param uuid the entity uuid
- * @return the entity with the given uuid, or null if an entity with that uuid does not exist
- */
- public static @Nullable WrapperEntity getEntity(UUID uuid) {
- checkInit();
- return entities.get(uuid);
- }
-
- /**
- * Registers a custom entity to EntityLib. This exists to allow developers to extend {@link WrapperEntity} and its subclasses simply and define their own logic.
- *
- * This method DOES NOT create a new entity, it simply registers the entity to EntityLib.
- * To construct a {@link WrapperEntity} you need to call {@link EntityLib#createMeta(int, EntityType)} and pass the created metadata to the constructor of the entity.
- *
- * This method will throw a RuntimeException if an entity with the given uuid or id already exists.
- *
- * The entity is not modified in any way, simply stored internally for it to be accessible thru {@link EntityLib#getEntity(UUID)} and {@link EntityLib#getEntity(int)}.
- *
- * @param entity the entity to register
- * @return the same entity passed.
- * @param instance of WrapperEntity, used to infer its type.
- */
- public static @NotNull T register(@NotNull T entity) {
- checkInit();
- if (entities.containsKey(entity.getUuid())) throw new RuntimeException("An entity with that uuid already exists");
- if (entitiesById.containsKey(entity.getEntityId())) throw new RuntimeException("An entity with that id already exists");
- entities.put(entity.getUuid(), entity);
- entitiesById.put(entity.getEntityId(), entity);
- return entity;
- }
-
- /**
- * Creates a new WrapperEntity with the given UUID and EntityType.
- * This method will automatically create a new EntityMeta for the entity and keeps track of it internally.
- * To get the entity, use {@link EntityLib#getEntity(UUID)} or {@link EntityLib#getEntity(int)}.
- *
- * In theoretically impossible cases, this method may return null.
- * @param uuid the entity uuid
- * @param entityType the entity type
- * @return the created entity, or null if the entity could not be created
- */
- public static @NotNull WrapperEntity createEntity(int entityId, UUID uuid, EntityType entityType) {
- checkInit();
- if (entities.containsKey(uuid)) throw new RuntimeException("An entity with that uuid already exists");
- if (entitiesById.containsKey(entityId)) throw new RuntimeException("An entity with that id already exists");
- EntityMeta meta = createMeta(entityId, entityType);
- WrapperEntity entity;
- if (meta instanceof LivingEntityMeta) {
- entity = new WrapperLivingEntity(entityId, uuid, entityType, meta);
- }
- else if (entityType == EntityTypes.EXPERIENCE_ORB) {
- entity = new WrapperExperienceOrbEntity(entityId, uuid, entityType, meta);
- }
- else {
- entity = new WrapperEntity(entityId, uuid, entityType, meta);
- }
- entities.put(uuid, entity);
- entitiesById.put(entityId, entity);
- return entity;
- }
-
- public static @NotNull WrapperEntity createEntity(@NotNull UUID uuid, EntityType entityType) {
- return createEntity(entityIdProvider.provide(), uuid, entityType);
- }
-
- public static @NotNull WrapperEntityCreature createEntityCreature(int entityId, @NotNull UUID uuid, @NotNull EntityType entityType) {
- checkInit();
- if (entities.containsKey(uuid)) throw new RuntimeException("An entity with that uuid already exists");
- if (entitiesById.containsKey(entityId)) throw new RuntimeException("An entity with that id already exists");
- EntityMeta meta = createMeta(entityId, entityType);
- if (!(meta instanceof LivingEntityMeta)) {
- throw new RuntimeException("Entity type " + entityType + " is not a living entity, EntityCreature requires a living entity");
- }
- WrapperEntityCreature entity = new WrapperEntityCreature(entityId, uuid, entityType, meta);
- entities.put(uuid, entity);
- entitiesById.put(entityId, entity);
- return entity;
- }
-
- public static @NotNull WrapperEntityCreature createEntityCreature(@NotNull UUID uuid, @NotNull EntityType entityType) {
- return createEntityCreature(entityIdProvider.provide(), uuid, entityType);
- }
-
- /**
- * @param entityId the entity id
- * @return the metadata of the entity with the given id. If the entity does not exist, this method will return null.
- */
- public static @Nullable EntityMeta getMeta(int entityId) {
- checkInit();
- return metadata.get(entityId);
- }
-
- /**
- * @param entityId the entity id
- * @param metaClass the metadata class to cast to
- * @return the metadata of the entity with the given id, cast to the given class. If the entity does not exist, this method will return null.
- * @param the metadata class
- */
- public static @Nullable T getMeta(int entityId, Class metaClass) {
- checkInit();
- EntityMeta meta = metadata.get(entityId);
- if (meta == null) {
- return null;
- }
- if (metaClass.isAssignableFrom(meta.getClass())) {
- return (T) meta;
- }
- return null;
- }
-
- /**
- * Creates a new EntityMeta for the given entity id and type, these are stored internally and can be retrieved using {@link EntityLib#getMeta(int)}.
- * @param entityId the entity id
- * @param entityType the entity type
- * @return the created EntityMeta
- */
- public static @NotNull EntityMeta createMeta(int entityId, EntityType entityType) {
- checkInit();
- Metadata m = new Metadata(entityId);
- BiFunction function = metaRegistry.get(entityType);
- EntityMeta meta = function.apply(entityId, m);
- metadata.put(entityId, meta);
- return meta;
- }
-
- /**
- * Creates a new EntityMeta for an entity, these are stored internally and can be retrieved using {@link EntityLib#getMeta(int)}.
- * @param entity the entity
- * @return the created EntityMeta
- */
- public static EntityMeta createMeta(WrapperEntity entity) {
- return createMeta(entity.getEntityId(), entity.getEntityType());
- }
-
- /**
- * @param entityType the entity type
- * @return the metadata class of the given entity type
- * @param gets the appropriate metadata class for the given entity type
- */
- public static Class getMetaClassOf(EntityType entityType) {
- return metaRegistry.getMetaClass(entityType);
- }
-
- /**
- * @return the packet events api instance that was used to initialize EntityLib
- */
- public static PacketEventsAPI> getPacketEvents() {
- checkInit();
- return packetEvents;
- }
-
- /**
- * @return the specified interaction processor, or null if none is specified
- */
- public static @Nullable EntityInteractionProcessor getInteractionProcessor() {
- return interactionProcessor;
- }
-
- /**
- * Sets the interaction processor to the given one.
- * @param interactionProcessor the interaction processor
- */
- public static void setInteractionProcessor(EntityInteractionProcessor interactionProcessor) {
- EntityLib.interactionProcessor = interactionProcessor;
- }
-
- /**
- * @return the entity id provider
- */
- public static EntityIdProvider getEntityIdProvider() {
- return entityIdProvider;
- }
-
- /**
- * Sets the entity id provider to the given one.
- * @param entityIdProvider the entity id provider. The default implementation can be found at {@link EntityIdProvider#simple()}
- */
- public static void setEntityIdProvider(EntityIdProvider entityIdProvider) {
- EntityLib.entityIdProvider = entityIdProvider;
- }
-
- /**
- * Another internal method to verify the server version is supported. Safe to use externally as its purpose is simple and to avoid code duplication
- */
- @ApiStatus.Internal
- public static void verifyVersion(ServerVersion supported, String msg) {
- if (packetEvents.getServerManager().getVersion().isOlderThan(supported)) {
- throw new InvalidVersionException(msg);
- }
- }
-
- /**
- * A primarily internal method to send a packet wrapper to a User from the users UUID. This is useful for methods in {@link WrapperEntity}. Safe to use externally as its purpose is simple and to avoid code duplication
- * @param user the user uuid
- * @param wrapper the packet wrapper
- */
- @ApiStatus.Internal
- public static void sendPacket(UUID user, PacketWrapper> wrapper) {
- checkInit();
- Object channel = packetEvents.getProtocolManager().getChannel(user);
- if (channel == null) {
- boolean b = Boolean.parseBoolean(System.getenv("entitylib_debug"));
- if (b) {
- System.out.println("EntityLib could not send packet to user " + user);
- }
- return;
- }
- packetEvents.getProtocolManager().sendPacket(channel, wrapper);
- }
-
- private static void checkInit() {
- if (!initialized) {
- throw new IllegalStateException("EntityLib is not initialized");
- }
- }
-}
diff --git a/src/main/java/me/tofaa/entitylib/Tickable.java b/src/main/java/me/tofaa/entitylib/Tickable.java
deleted file mode 100644
index b1690f0..0000000
--- a/src/main/java/me/tofaa/entitylib/Tickable.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package me.tofaa.entitylib;
-
-public interface Tickable {
-
- /** Internal method for actual logic ticking, if you want to add custom logic to your entity, override {@link #tick(long)} instead. */
- default void update(long time) {
-
- }
-
- void tick(long time);
-
-}
diff --git a/src/main/java/me/tofaa/entitylib/TickingContainer.java b/src/main/java/me/tofaa/entitylib/TickingContainer.java
deleted file mode 100644
index 535608b..0000000
--- a/src/main/java/me/tofaa/entitylib/TickingContainer.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package me.tofaa.entitylib;
-
-/**
- * A container that can hold and tick {@link Tickable}s.
- * This is for specific users to extend if they want ticking functionality.
- *
- */
-public interface TickingContainer {
-
- void addTickable(Tickable tickable);
-
- void removeTickable(Tickable tickable);
-
- default void update(long time) {
- for (Tickable tickable : getTickables()) {
- tickable.update(time);
- }
- }
-
- Iterable getTickables();
-
-}
diff --git a/src/main/java/me/tofaa/entitylib/entity/EntityIdProvider.java b/src/main/java/me/tofaa/entitylib/entity/EntityIdProvider.java
deleted file mode 100644
index b461786..0000000
--- a/src/main/java/me/tofaa/entitylib/entity/EntityIdProvider.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package me.tofaa.entitylib.entity;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-@FunctionalInterface
-public interface EntityIdProvider {
-
- static EntityIdProvider simple() {
- return new EntityIdProvider() {
- private final AtomicInteger atomicInteger = new AtomicInteger(0);
- @Override
- public int provide() {
- return atomicInteger.incrementAndGet();
- }
- };
- }
-
-
- int provide();
-}
diff --git a/src/main/java/me/tofaa/entitylib/entity/EntityInteractionProcessor.java b/src/main/java/me/tofaa/entitylib/entity/EntityInteractionProcessor.java
deleted file mode 100644
index 5eb6c79..0000000
--- a/src/main/java/me/tofaa/entitylib/entity/EntityInteractionProcessor.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package me.tofaa.entitylib.entity;
-
-import com.github.retrooper.packetevents.protocol.player.InteractionHand;
-import com.github.retrooper.packetevents.protocol.player.User;
-import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
-import org.jetbrains.annotations.NotNull;
-
-@FunctionalInterface
-public interface EntityInteractionProcessor {
-
- void process(
- @NotNull WrapperEntity entity,
- @NotNull WrapperPlayClientInteractEntity.InteractAction action,
- @NotNull InteractionHand hand,
- @NotNull User user
- );
-
-}
diff --git a/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java b/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java
deleted file mode 100644
index 54c5e5e..0000000
--- a/src/main/java/me/tofaa/entitylib/entity/WrapperLivingEntity.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package me.tofaa.entitylib.entity;
-
-import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
-import com.github.retrooper.packetevents.util.Vector3d;
-import com.github.retrooper.packetevents.util.Vector3f;
-import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityStatus;
-import me.tofaa.entitylib.meta.EntityMeta;
-import me.tofaa.entitylib.meta.types.LivingEntityMeta;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.UUID;
-
-public class WrapperLivingEntity extends WrapperEntity{
-
- private final WrapperEntityEquipment equipment;
- private float maxHealth;
-
- public WrapperLivingEntity(int entityId, @NotNull UUID uuid, EntityType entityType, EntityMeta meta) {
- super(entityId, uuid, entityType, meta);
- this.equipment = new WrapperEntityEquipment(this);
- }
-
-
- public void kill() {
- sendStatus((byte) 3);
- setHealth(0);
- this.velocity = Vector3d.zero();
- }
-
- public void sendStatus(byte status) {
- sendPacketsToViewers(new WrapperPlayServerEntityStatus(getEntityId(), status));
- }
-
- public float getHealth() {
- return getMeta().getHealth();
- }
-
- public void setHealth(float health) {
- getMeta().setHealth(Math.min(Math.max(health, 0), getMaxHealth()));
- }
-
- public float getMaxHealth() {
- return maxHealth;
- }
-
- public void setMaxHealth(float maxHealth) {
- this.maxHealth = maxHealth;
- }
-
- public WrapperEntityEquipment getEquipment() {
- return equipment;
- }
-
- @Override
- public LivingEntityMeta getMeta() {
- return (LivingEntityMeta) super.getMeta();
- }
-}
diff --git a/src/main/java/me/tofaa/entitylib/meta/Metadata.java b/src/main/java/me/tofaa/entitylib/meta/Metadata.java
deleted file mode 100644
index 8dd0d57..0000000
--- a/src/main/java/me/tofaa/entitylib/meta/Metadata.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package me.tofaa.entitylib.meta;
-
-import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
-import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
-import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
-import me.tofaa.entitylib.EntityLib;
-import me.tofaa.entitylib.entity.WrapperEntity;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-@SuppressWarnings("unchecked")
-public class Metadata {
-
- private final Map metadataMap = new ConcurrentHashMap<>();
- private final int entityId;
-
- public Metadata(int entityId) {
- this.entityId = entityId;
- }
-
- public T getIndex(byte index, @Nullable T defaultValue) {
- EntityData entityData = metadataMap.get(index);
- if (entityData == null) return defaultValue;
- if (entityData.getValue() == null) return defaultValue;
- return (T) entityData.getValue();
- }
-
- public void setIndex(byte index, @NotNull EntityDataType dataType, T value) {
- EntityData data = new EntityData(index, dataType, value);
- this.metadataMap.put(index, data);
- WrapperEntity e = EntityLib.getEntity(entityId);
- if (e != null && e.hasSpawned()) {
- e.sendPacketToViewers(
- new WrapperPlayServerEntityMetadata(
- entityId,
- getEntries()
- )
- );
- }
- }
-
- @NotNull List getEntries() {
- return new ArrayList<>(metadataMap.values());
- }
-
- public WrapperPlayServerEntityMetadata createPacket() {
- return new WrapperPlayServerEntityMetadata(entityId, getEntries());
- }
-
-}
diff --git a/test-plugin/build.gradle b/test-plugin/build.gradle
index f8a7b47..69caf37 100644
--- a/test-plugin/build.gradle
+++ b/test-plugin/build.gradle
@@ -27,11 +27,14 @@ repositories {
dependencies {
compileOnly('org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT')
compileOnly('com.github.retrooper.packetevents:spigot:2.0.2')
- implementation project(':')
+ implementation(project(":platforms:spigot"))
}
tasks {
runServer {
- minecraftVersion("1.19.4")
+ minecraftVersion("1.20.4")
+ downloadPlugins {
+ modrinth("packetevents", "2.2.1")
+ }
}
}
\ No newline at end of file
diff --git a/test-plugin/src/main/java/me/tofaa/entitylib/EntityLibPlugin.java b/test-plugin/src/main/java/me/tofaa/entitylib/EntityLibPlugin.java
deleted file mode 100644
index 90bdea9..0000000
--- a/test-plugin/src/main/java/me/tofaa/entitylib/EntityLibPlugin.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package me.tofaa.entitylib;
-
-import com.github.retrooper.packetevents.PacketEvents;
-import com.github.retrooper.packetevents.protocol.player.InteractionHand;
-import com.github.retrooper.packetevents.protocol.player.User;
-import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
-import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCloseWindow;
-import me.tofaa.entitylib.entity.EntityInteractionProcessor;
-import me.tofaa.entitylib.entity.WrapperEntity;
-import org.bukkit.plugin.java.JavaPlugin;
-import org.jetbrains.annotations.NotNull;
-
-public final class EntityLibPlugin extends JavaPlugin {
-
- static EntityLibPlugin instance;
-
- @Override
- public void onEnable() {
- EntityLib.init(PacketEvents.getAPI());
- EntityLib.enableEntityInteractions();
- EntityLib.setInteractionProcessor((entity, action, hand, user) -> user.sendMessage("Hello World"));
-
- TestDisplayCommand testDisplayCommand = new TestDisplayCommand();
- getCommand("testdisplay").setExecutor(testDisplayCommand);
- getCommand("testdisplay").setTabCompleter(testDisplayCommand);
-
- getCommand("testapi").setExecutor(new TestCommand());
- getCommand("testentity").setExecutor(new TestEntityCommand());
- getCommand("spawnclickablefrog").setExecutor(new SpawnClickableFrogCommand());
- instance = this;
- }
-}
diff --git a/test-plugin/src/main/java/me/tofaa/entitylib/SpawnClickableFrogCommand.java b/test-plugin/src/main/java/me/tofaa/entitylib/SpawnClickableFrogCommand.java
deleted file mode 100644
index 54c72ff..0000000
--- a/test-plugin/src/main/java/me/tofaa/entitylib/SpawnClickableFrogCommand.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package me.tofaa.entitylib;
-
-import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
-import io.github.retrooper.packetevents.util.SpigotConversionUtil;
-import me.tofaa.entitylib.entity.WrapperEntity;
-import me.tofaa.entitylib.meta.mobs.FrogMeta;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Bukkit;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitTask;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-
-public class SpawnClickableFrogCommand implements CommandExecutor {
-
- private final Map updateTasks = new HashMap<>();
- private final FrogMeta.Variant[] variants = FrogMeta.Variant.values();
-
- @Override
- public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- Player player = (Player) commandSender;
- WrapperEntity e = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.TEXT_DISPLAY);
- FrogMeta meta = (FrogMeta) e.getMeta();
- meta.setHasGlowingEffect(true);
- meta.setCustomNameVisible(true);
- meta.setCustomName(Component.text("CLICK ME!"));
- updateTasks.put(e, Bukkit.getScheduler().runTaskTimerAsynchronously(
- EntityLibPlugin.instance,
- new Runnable() {
- int i = 0;
- Random random = new Random();
-
- @Override
- public void run() {
- if (!e.hasSpawned()) return;
- int r = random.nextInt(2);
- meta.setVariant(variants[r]);
- meta.setCustomName(Component.text("CLICKED: " + i + " TIMES"));
- }
- },
- 20, 20));
- e.addViewer(player.getUniqueId());
- e.spawn(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
- return false;
- }
-}
diff --git a/test-plugin/src/main/java/me/tofaa/entitylib/TestCommand.java b/test-plugin/src/main/java/me/tofaa/entitylib/TestCommand.java
deleted file mode 100644
index 60d4267..0000000
--- a/test-plugin/src/main/java/me/tofaa/entitylib/TestCommand.java
+++ /dev/null
@@ -1,49 +0,0 @@
-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 org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.UUID;
-
-public class TestCommand implements CommandExecutor {
-
- private WrapperEntity base, passenger;
-
- @Override
- public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
- if (!(sender instanceof Player)) return false;
- Player player = (Player) sender;
-
- if (base != null) {
- if (base.hasPassenger(passenger)) {
- base.removePassenger(passenger);
- player.sendMessage("Removed");
- return true;
- }
- }
- else {
- base = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.SHEEP);
- passenger = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.SKELETON);
- }
-
- Location location = SpigotConversionUtil.fromBukkitLocation(player.getLocation());
- Location pass = new Location(location.getX() + 1, location.getY(), location.getZ(), location.getYaw(), location.getPitch());
-
- base.addViewer(player.getUniqueId());
- passenger.addViewer(player.getUniqueId());
- base.spawn(location);
- passenger.spawn(pass);
- base.addPassenger(player.getEntityId());
- player.sendMessage("Spawned");
-
- return true;
- }
-
-}
diff --git a/test-plugin/src/main/java/me/tofaa/entitylib/TestDisplayCommand.java b/test-plugin/src/main/java/me/tofaa/entitylib/TestDisplayCommand.java
deleted file mode 100644
index b003f08..0000000
--- a/test-plugin/src/main/java/me/tofaa/entitylib/TestDisplayCommand.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package me.tofaa.entitylib;
-
-import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
-import com.github.retrooper.packetevents.protocol.item.ItemStack;
-import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
-import com.github.retrooper.packetevents.protocol.world.Location;
-import com.github.retrooper.packetevents.util.Vector3d;
-import com.github.retrooper.packetevents.util.Vector3f;
-import io.github.retrooper.packetevents.util.SpigotConversionUtil;
-import me.tofaa.entitylib.entity.WrapperEntity;
-import me.tofaa.entitylib.meta.display.BlockDisplayMeta;
-import me.tofaa.entitylib.meta.display.ItemDisplayMeta;
-import me.tofaa.entitylib.meta.display.TextDisplayMeta;
-import me.tofaa.entitylib.meta.types.DisplayMeta;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Material;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.command.TabCompleter;
-import org.bukkit.entity.Player;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-
-public class TestDisplayCommand implements CommandExecutor, TabCompleter {
-
- @Override
- public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- if (strings.length == 0) return false;
- String type = strings[0];
- Player player = (Player) commandSender;
- switch (type) {
- case "block":
- block(player);
- break;
- case "text":
- text(player);
- break;
- case "item":
- item(player);
- break;
- }
- return false;
- }
-
-
-
- private void block(Player player) {
- WrapperEntity e = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.BLOCK_DISPLAY);
- BlockDisplayMeta meta = (BlockDisplayMeta) e.getMeta();
- meta.setHasGlowingEffect(true);
- meta.setBlockId(SpigotConversionUtil.fromBukkitBlockData(Material.ACACIA_LOG.createBlockData()).getGlobalId());
- meta.setBillboardConstraints(DisplayMeta.BillboardConstraints.CENTER);
- meta.setScale(new Vector3f(2, 2, 2));
- e.addViewer(player.getUniqueId());
- e.spawn(fromPlayer(player));
- }
-
- private void text(Player player) {
- WrapperEntity e = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.TEXT_DISPLAY);
- TextDisplayMeta meta = (TextDisplayMeta) e.getMeta();
- meta.setHasGlowingEffect(true);
- meta.setText(Component.text("Hello World!"));
- meta.setBillboardConstraints(DisplayMeta.BillboardConstraints.CENTER);
- meta.setTranslation(new Vector3f(4.0f, 0.0f, 0.0f));
- meta.setScale(new Vector3f(2, 2, 2));
- e.addViewer(player.getUniqueId());
- e.spawn(fromPlayer(player));
- }
-
- private void item(Player player) {
- WrapperEntity e = EntityLib.createEntity(UUID.randomUUID(), EntityTypes.ITEM_DISPLAY);
- ItemDisplayMeta meta = (ItemDisplayMeta) e.getMeta();
- meta.setDisplayType(ItemDisplayMeta.DisplayType.FIRST_PERSON_LEFT_HAND);
- meta.setItem(ItemStack.builder()
- .type(ItemTypes.ACACIA_BOAT).build()
- );
- e.addViewer(player.getUniqueId());
- e.spawn(fromPlayer(player));
- }
-
- private static Location fromPlayer(Player player) {
- return new Location(player.getLocation().getX(), player.getLocation().getY() + 2, player.getLocation().getZ(), 0f, 0f);
- }
-
- @Nullable
- @Override
- public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
- return strings.length == 1 ? Arrays.asList("block", "text", "item") : null;
- }
-}
diff --git a/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java b/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java
deleted file mode 100644
index beeb1c6..0000000
--- a/test-plugin/src/main/java/me/tofaa/entitylib/TestEntityCommand.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package me.tofaa.entitylib;
-
-import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
-import io.github.retrooper.packetevents.util.SpigotConversionUtil;
-import me.tofaa.entitylib.entity.WrapperEntityEquipment;
-import me.tofaa.entitylib.entity.WrapperLivingEntity;
-import me.tofaa.entitylib.meta.EntityMeta;
-import net.kyori.adventure.text.Component;
-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.UUID;
-
-public class TestEntityCommand implements CommandExecutor {
-
- private WrapperLivingEntity entity;
-
- @Override
- public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
- if (!(sender instanceof Player )) return false;
- Player player = (Player) sender;
- if (entity == null) {
- entity = (WrapperLivingEntity) EntityLib.createEntity(UUID.randomUUID(), EntityTypes.ZOMBIE);
- if (entity == null) {
- player.sendMessage("idk");
- return false;
- }
- entity.addViewer(player.getUniqueId());
- entity.spawn(SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
- }
- equipItems(player);
- EntityMeta meta = entity.getMeta();
-
- meta.setCustomNameVisible(!meta.isCustomNameVisible());
- meta.setCustomName(Component.text("test"));
-
- entity.refresh();
- return false;
- }
-
- private void equipItems(Player player) {
- ItemStack held = player.getInventory().getItemInMainHand();
- ItemStack helmet = player.getInventory().getHelmet();
- ItemStack chestplate = player.getInventory().getChestplate();
- ItemStack leggings = player.getInventory().getLeggings();
- ItemStack boots = player.getInventory().getBoots();
- WrapperEntityEquipment equipment = entity.getEquipment();
-
- if (helmet != null && !helmet.getType().isAir()) equipment.setHelmet(SpigotConversionUtil.fromBukkitItemStack(helmet));
- if (chestplate != null && !chestplate.getType().isAir()) equipment.setChestplate(SpigotConversionUtil.fromBukkitItemStack(chestplate));
- if (leggings != null && !leggings.getType().isAir()) equipment.setLeggings(SpigotConversionUtil.fromBukkitItemStack(leggings));
- if (boots != null && !boots.getType().isAir()) equipment.setBoots(SpigotConversionUtil.fromBukkitItemStack(boots));
- if (!held.getType().isAir()) equipment.setMainHand(SpigotConversionUtil.fromBukkitItemStack(held));
- }
-
-}
diff --git a/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java b/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java
new file mode 100644
index 0000000..32046b3
--- /dev/null
+++ b/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java
@@ -0,0 +1,58 @@
+package me.tofaa.testentitylib;
+
+import com.github.retrooper.packetevents.PacketEvents;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import io.github.retrooper.packetevents.util.SpigotConversionUtil;
+import me.tofaa.entitylib.APIConfig;
+import me.tofaa.entitylib.EntityLib;
+import me.tofaa.entitylib.meta.mobs.passive.ChickenMeta;
+import me.tofaa.entitylib.spigot.SpigotEntityLibAPI;
+import me.tofaa.entitylib.spigot.SpigotEntityLibPlatform;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.NotNull;
+
+public class TestEntityLibPlugin extends JavaPlugin implements CommandExecutor {
+
+
+ private SpigotEntityLibAPI api;
+ private WrapperEntity e;
+
+ @Override
+ public void onEnable() {
+
+ SpigotEntityLibPlatform platform = new SpigotEntityLibPlatform(this);
+ APIConfig settings = new APIConfig(PacketEvents.getAPI())
+ .debugMode()
+ .tickTickables()
+ .usePlatformLogger();
+
+ EntityLib.init(platform, settings);
+ api = platform.getAPI();
+ getCommand("testapi").setExecutor(this);
+ }
+
+ @Override
+ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
+ if (!(sender instanceof Player)) return false;
+ Player player = (Player) sender;
+ if (e == null) {
+ e = api.spawnEntity(EntityTypes.CHICKEN, SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
+ e.addViewer(player.getUniqueId());
+ player.sendMessage("Spawned");
+ }
+ ChickenMeta meta = (ChickenMeta) e.getEntityMeta();
+ meta.setBaby(!meta.isBaby());
+ meta.setHasGlowingEffect(!meta.hasGlowingEffect());
+ meta.setHasNoGravity(!meta.hasNoGravity());
+
+ player.sendMessage("Updated");
+ return true;
+ }
+
+}
diff --git a/test-plugin/src/main/resources/plugin.yml b/test-plugin/src/main/resources/plugin.yml
index 6fbc2c9..8c23a0e 100644
--- a/test-plugin/src/main/resources/plugin.yml
+++ b/test-plugin/src/main/resources/plugin.yml
@@ -2,19 +2,9 @@ name: EntityLibPlugin
version: 1.0.0
depend:
- packetevents
-main: me.tofaa.entitylib.EntityLibPlugin
+main: me.tofaa.testentitylib.TestEntityLibPlugin
api-version: "1.19"
commands:
testapi:
- description: Test PEEntityMeta API
- usage: /
-
- testentity:
- description: Test PEEntity API
- usage: /
- testdisplay:
- description: Test PEDisplay API
- usage: /
- spawnclickablefrog:
- description: Spawn a clickable frog
+ description: Test EntityLib API
usage: /
\ No newline at end of file