From 2d76a9eac8f8d4a1c393c072ac421ea964077dcb Mon Sep 17 00:00:00 2001 From: Tofaa <82680183+Tofaa2@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:44:02 +0400 Subject: [PATCH] Introduce changes notification for meta Introduces a system to avoid spam sending metadata packets by stopping sending, changing the metadata, then sending it all at once --- .idea/workspace.xml | 20 +- .../java/me/tofaa/entitylib/EntityLibAPI.java | 22 + .../me/tofaa/entitylib/meta/EntityMeta.java | 41 +- .../entitylib/meta/MetaOffsetConverter.java | 580 ++++++++++++------ .../me/tofaa/entitylib/meta/Metadata.java | 73 ++- .../entitylib/wrapper/WrapperEntity.java | 2 +- .../java/me/tofaa/entitylib/codegen/Main.java | 8 +- .../src/main/resources/offset-calculator.json | 238 ++++++- .../common/AbstractEntityLibAPI.java | 21 + .../common/AbstractWorldWrapper.java | 3 + .../spigot/SpigotEntityLibPlatform.java | 2 +- .../testentitylib/TestEntityLibPlugin.java | 28 +- test-plugin/src/main/resources/plugin.yml | 12 +- 13 files changed, 792 insertions(+), 258 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 5913b97..3f14df4 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,9 +5,19 @@ - - + + + + + + + + + + + + @@ -292,7 +303,8 @@ - + + diff --git a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java index 5276ee7..d2227bf 100644 --- a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java +++ b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java @@ -3,7 +3,9 @@ package me.tofaa.entitylib; import com.github.retrooper.packetevents.PacketEventsAPI; import me.tofaa.entitylib.tick.TickContainer; import me.tofaa.entitylib.wrapper.WrapperEntity; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -26,6 +28,26 @@ public interface EntityLibAPI { void onEnable(); + /** + * Attempts to search and find an entity across all wrapped worlds. This only works on EntityLib entities. + * @param entityId the entity id of the entity + * @return the entity if one is found, null otherwise. + */ + @Nullable WrapperEntity findEntity(int entityId); + + /** + * Mainly internal method to register the {@link WrapperEntity} to EntitLib cache, all {@link WorldWrapper}'s do this automatically + * @param entity + */ + @ApiStatus.Internal + void globalRegisterEntity(@NotNull WrapperEntity entity); + + /** + * Mainly internal method to unregister the {@link WrapperEntity} to EntitLib cache, all {@link WorldWrapper}'s do this automatically + * @param entity + */ + void globalUnregisterEntity(@NotNull WrapperEntity entity); + /** * Creates a wrapped world for the platform specific world. diff --git a/api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java b/api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java index 5150aa5..0957521 100644 --- a/api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java +++ b/api/src/main/java/me/tofaa/entitylib/meta/EntityMeta.java @@ -19,7 +19,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; -import java.util.function.Function; + +import static me.tofaa.entitylib.meta.MetaOffsetConverter.EntityMetaOffsets.*; public class EntityMeta implements EntityMetadataProvider { @@ -65,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); } @@ -122,59 +131,59 @@ public class EntityMeta implements EntityMetadataProvider { } public short getAirTicks() { - return this.metadata.getIndex((byte) 1, (short) 300); + return this.metadata.getIndex(airTicksOffset(), (short) 300); } public void setAirTicks(short value) { - this.metadata.setIndex((byte) 1, EntityDataTypes.SHORT, value); + this.metadata.setIndex(airTicksOffset(), EntityDataTypes.SHORT, value); } public Component getCustomName() { - return this.metadata.getIndex(offset(OFFSET, 2), null); + return this.metadata.getIndex(customNameOffset(), null); } public void setCustomName(Component value) { - this.metadata.setIndex(offset(OFFSET, 2), EntityDataTypes.ADV_COMPONENT, value); + this.metadata.setIndex(customNameOffset(), EntityDataTypes.ADV_COMPONENT, value); } public boolean isCustomNameVisible() { - return this.metadata.getIndex(offset(OFFSET, 3), false); + return this.metadata.getIndex(customNameVisibleOffset(), false); } public void setCustomNameVisible(boolean value) { - this.metadata.setIndex(offset(OFFSET, 3), EntityDataTypes.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() { diff --git a/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java b/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java index 0848013..aaae37b 100644 --- a/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java +++ b/api/src/main/java/me/tofaa/entitylib/meta/MetaOffsetConverter.java @@ -10,250 +10,426 @@ import org.jetbrains.annotations.ApiStatus; @SuppressWarnings("unused") public final class MetaOffsetConverter { private MetaOffsetConverter() { + } - public static byte airTicksOffset() { - int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion(); - if (protocolVersion >= 47 && protocolVersion <= 47) { - return 1; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - throw new RuntimeException("Unknown protocol version for this method"); - } - public static byte interpolationDelayOffset() { - int protocolVersion = getApi().getPacketEvents().getServerManager().getVersion().getProtocolVersion(); - if (protocolVersion >= 762 && protocolVersion <= 765) { - return 8; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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; + 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"); } - 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 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 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"); } } diff --git a/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java b/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java index 532472a..da5adbf 100644 --- a/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java +++ b/api/src/main/java/me/tofaa/entitylib/meta/Metadata.java @@ -3,38 +3,91 @@ 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.ArrayList; -import java.util.List; -import java.util.Map; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; @SuppressWarnings("unchecked") public class Metadata { - private final Map metadataMap = new ConcurrentHashMap<>(); 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) { - EntityData entityData = metadataMap.get(index); - if (entityData == null) return defaultValue; - if (entityData.getValue() == null) return defaultValue; - return (T) entityData.getValue(); + 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); - this.metadataMap.put(index, data); + entries[index] = data; + this.entryMap = null; + + final WrapperEntity entity = EntityLib.getApi().findEntity(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().findEntity(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 new ArrayList<>(metadataMap.values()); + return Collections.unmodifiableList(Arrays.asList(entries)); } public WrapperPlayServerEntityMetadata createPacket() { diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java index 2402c85..d1078fc 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java @@ -331,7 +331,7 @@ public class WrapperEntity implements Tickable { } public boolean hasNoGravity() { - return entityMeta.isHasNoGravity(); + return entityMeta.hasNoGravity(); } public void setHasNoGravity(boolean hasNoGravity) { 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 index 4567f29..def0633 100644 --- a/code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java +++ b/code-gen/src/main/java/me/tofaa/entitylib/codegen/Main.java @@ -44,6 +44,10 @@ public final class Main { 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") @@ -58,10 +62,12 @@ public final class Main { method.endControlFlow(); } method.addStatement("throw new RuntimeException(\"Unknown protocol version for this method\")"); - baseBuilder.addMethod(method.build()); + 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) diff --git a/code-gen/src/main/resources/offset-calculator.json b/code-gen/src/main/resources/offset-calculator.json index 414516a..079092b 100644 --- a/code-gen/src/main/resources/offset-calculator.json +++ b/code-gen/src/main/resources/offset-calculator.json @@ -6,7 +6,7 @@ "name": "airTicks", "checks": [ { - "from": 47, + "from": 765, "to": 47, "offset": 1 } @@ -74,6 +74,9 @@ } ] }, + + + { "class-name": "AbstractDisplayMeta", "offsets": [ @@ -310,7 +313,7 @@ ] }, { - "class-name": "ItemDisplay", + "class-name": "ItemDisplayMeta", "offsets": [ { "name": "item", @@ -343,5 +346,236 @@ ] } ] + }, + { + "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/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java b/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java index 2433496..0f20a0e 100644 --- a/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java +++ b/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java @@ -7,11 +7,15 @@ import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.EntityLibAPI; import me.tofaa.entitylib.Platform; import me.tofaa.entitylib.tick.TickContainer; +import me.tofaa.entitylib.wrapper.WrapperEntity; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractEntityLibAPI implements EntityLibAPI { @@ -19,6 +23,7 @@ public abstract class AbstractEntityLibAPI implements EntityLibAPI packetEvents; protected final APIConfig settings; protected final Collection> tickContainers; + protected final Map globalEntityMap = new ConcurrentHashMap<>(); protected AbstractEntityLibAPI(Platform

platform, APIConfig settings) { this.platform = platform; @@ -27,6 +32,22 @@ public abstract class AbstractEntityLibAPI implements EntityLibAPI() : Collections.emptyList(); } + @Override + public @Nullable WrapperEntity findEntity(int entityId) { + return globalEntityMap.get(entityId); + } + + @Override + public void globalRegisterEntity(WrapperEntity entity) { + if (globalEntityMap.containsKey(entity.getEntityId())) throw new IllegalArgumentException("Entity with that Id is already registered and present"); + globalEntityMap.put(entity.getEntityId(), entity); + } + + @Override + public void globalUnregisterEntity(@NotNull WrapperEntity entity) { + globalEntityMap.remove(entity.getEntityId()); + } + @NotNull @Override public APIConfig getSettings() { diff --git a/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java b/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java index b7a29fd..311c176 100644 --- a/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java +++ b/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java @@ -54,6 +54,7 @@ public abstract class AbstractWorldWrapper implements WorldWrapper { player.spawn(this, location); entities.put(player.getUuid(), player); entitiesById.put(player.getEntityId(), player); + EntityLib.getApi().globalRegisterEntity(player); return player; } @@ -62,6 +63,7 @@ public abstract class AbstractWorldWrapper implements WorldWrapper { entity.spawn(this, location); entities.put(entity.getUuid(), entity); entitiesById.put(entity.getEntityId(), entity); + EntityLib.getApi().globalRegisterEntity(entity); return entity; } @@ -70,6 +72,7 @@ public abstract class AbstractWorldWrapper implements WorldWrapper { entity.despawn(); this.entities.remove(entity.getUuid()); this.entitiesById.remove(entity.getEntityId()); + EntityLib.getApi().globalUnregisterEntity(entity); } @Override 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 index 919fa12..fd509b0 100644 --- a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java +++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java @@ -25,7 +25,7 @@ public class SpigotEntityLibPlatform extends AbstractPlatform { @Override - public EntityLibAPI getAPI() { + public SpigotEntityLibAPI getAPI() { return api; } diff --git a/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java b/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java index 849ec69..b583bb0 100644 --- a/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java +++ b/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java @@ -8,20 +8,25 @@ import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.EntityLibAPI; import me.tofaa.entitylib.WorldWrapper; 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.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; -public class TestEntityLibPlugin extends JavaPlugin implements Listener { +public class TestEntityLibPlugin extends JavaPlugin implements CommandExecutor { - private EntityLibAPI api; + private SpigotEntityLibAPI api; private WrapperEntity e; private WorldWrapper world; @@ -35,24 +40,27 @@ public class TestEntityLibPlugin extends JavaPlugin implements Listener { .usePlatformLogger(); EntityLib.init(platform, settings); - api = EntityLib.getApi(); - getServer().getPluginManager().registerEvents(this, this); + api = platform.getAPI(); + getCommand("testapi").setExecutor(this); } - @EventHandler - public void onCrouch(PlayerToggleSneakEvent event) { - Player player = event.getPlayer(); + @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) { world = api.wrapWorld(player.getWorld()); e = world.spawnEntity(EntityTypes.CHICKEN, SpigotConversionUtil.fromBukkitLocation(player.getLocation())); + e.addViewer(player.getUniqueId()); + player.sendMessage("Spawned"); } - world = api.wrapWorld(player.getWorld()); - e = world.spawnEntity(EntityTypes.CHICKEN, SpigotConversionUtil.fromBukkitLocation(player.getLocation())); ChickenMeta meta = (ChickenMeta) e.getEntityMeta(); meta.setBaby(!meta.isBaby()); meta.setHasGlowingEffect(!meta.hasGlowingEffect()); + meta.setHasNoGravity(!meta.hasNoGravity()); - e.addViewer(player.getUniqueId()); + player.sendMessage("Updated"); + return true; } } diff --git a/test-plugin/src/main/resources/plugin.yml b/test-plugin/src/main/resources/plugin.yml index df284e5..8c23a0e 100644 --- a/test-plugin/src/main/resources/plugin.yml +++ b/test-plugin/src/main/resources/plugin.yml @@ -6,15 +6,5 @@ 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