diff --git a/api/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java b/api/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java index 389b721a436..714082a3c65 100644 --- a/api/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java +++ b/api/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java @@ -25,14 +25,12 @@ package org.geysermc.geyser.api.connection; -import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.index.qual.Positive; import org.geysermc.api.connection.Connection; import org.geysermc.geyser.api.bedrock.camera.CameraData; import org.geysermc.geyser.api.bedrock.camera.CameraShake; import org.geysermc.geyser.api.command.CommandSource; import org.geysermc.geyser.api.entity.EntityData; -import org.geysermc.geyser.api.entity.type.GeyserEntity; import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; import org.geysermc.geyser.api.skin.SkinData; import org.jspecify.annotations.Nullable; @@ -40,7 +38,6 @@ import java.util.NoSuchElementException; import java.util.Set; import java.util.UUID; -import java.util.concurrent.CompletableFuture; /** * Represents a player connection used in Geyser. @@ -57,7 +54,7 @@ public interface GeyserConnection extends Connection, CommandSource { /** * Exposes the {@link EntityData} for this connection. - * It allows you to get entities by their Java entity ID, show emotes, and get the player entity. + * It allows you to look up other entities through various methods. * * @return the EntityData for this connection. */ @@ -164,14 +161,6 @@ public interface GeyserConnection extends Connection, CommandSource { */ void sendSkin(UUID player, SkinData skinData); - /** - * @param javaId the Java entity ID to look up. - * @return a {@link GeyserEntity} if present in this connection's entity tracker. - * @deprecated Use {@link EntityData#entityByJavaId(int)} instead - */ - @Deprecated - CompletableFuture<@Nullable GeyserEntity> entityByJavaId(@NonNegative int javaId); - /** * Displays a player entity as emoting to this client. * diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/EntityData.java b/api/src/main/java/org/geysermc/geyser/api/entity/EntityData.java index 44c0254e0ef..4bf5682782e 100644 --- a/api/src/main/java/org/geysermc/geyser/api/entity/EntityData.java +++ b/api/src/main/java/org/geysermc/geyser/api/entity/EntityData.java @@ -40,13 +40,29 @@ */ public interface EntityData { + /** + * @deprecated use {@link #byJavaId(int)} + */ + @Deprecated + CompletableFuture<@Nullable GeyserEntity> entityByJavaId(@NonNegative int javaId); + /** * Returns a {@link GeyserEntity} to e.g. make them play an emote. * * @param javaId the Java entity ID to look up * @return a {@link GeyserEntity} if present in this connection's entity tracker */ - CompletableFuture<@Nullable GeyserEntity> entityByJavaId(@NonNegative int javaId); + @Nullable GeyserEntity byJavaId(@NonNegative int javaId); + + /** + * Returns a {@link GeyserEntity} to e.g. update entity properties. + */ + @Nullable GeyserEntity byUuid(UUID javaUuid); + + /** + * Returns a {@link GeyserEntity} based on a Geyser entity id + */ + @Nullable GeyserEntity byGeyserId(@NonNegative long geyserId); /** * (Un)locks the client's movement inputs, so that they cannot move. diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/custom/CustomEntityDefinition.java b/api/src/main/java/org/geysermc/geyser/api/entity/custom/CustomEntityDefinition.java new file mode 100644 index 00000000000..929707b7a79 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/custom/CustomEntityDefinition.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.custom; + +import org.geysermc.geyser.api.GeyserApi; +import org.geysermc.geyser.api.entity.definition.GeyserEntityDefinition; +import org.geysermc.geyser.api.util.Identifier; + +/** + * Represents a custom entity definition for a non-vanilla, custom Bedrock entity. + */ +public interface CustomEntityDefinition extends GeyserEntityDefinition { + + @Override + default boolean vanilla() { + return false; + } + + /** + * Creates or retrieves a GeyserEntityDefinition by the Bedrock entity type identifier. + * + * @param identifier the Bedrock entity identifier + * @return the CustomEntityDefinition + */ + static CustomEntityDefinition of(Identifier identifier) { + if (identifier.vanilla()) { + throw new IllegalArgumentException("Use GeyserEntityDefinition#of for vanilla entity lookups!"); + } + return GeyserApi.api().provider(CustomEntityDefinition.class, identifier); + } + + /** + * Creates or retrieves a GeyserEntityDefinition by the Bedrock entity type identifier. + * + * @param identifier the Bedrock entity identifier, in string format + * @return the CustomEntityDefinition + */ + static CustomEntityDefinition of(String identifier) { + return of(Identifier.of(identifier)); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/custom/CustomJavaEntityType.java b/api/src/main/java/org/geysermc/geyser/api/entity/custom/CustomJavaEntityType.java new file mode 100644 index 00000000000..be5d27eacdf --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/custom/CustomJavaEntityType.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.custom; + +import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.common.returnsreceiver.qual.This; +import org.geysermc.geyser.api.entity.definition.GeyserEntityDefinition; +import org.geysermc.geyser.api.entity.definition.JavaEntityType; +import org.geysermc.geyser.api.event.lifecycle.GeyserDefineEntitiesEvent; +import org.geysermc.geyser.api.util.Identifier; +import org.jspecify.annotations.Nullable; + +/** + * Represents a custom Minecraft: Java Edition entity type. + * This can only be used with modded servers! + */ +public interface CustomJavaEntityType extends JavaEntityType { + + @Override + default boolean vanilla() { + return false; + } + + interface Builder { + + /** + * The entity type's identifier. It cannot be in the Minecraft namespace + * for custom entities! + * + * @param entityType the identifier + * @return this builder + */ + @This Builder type(Identifier entityType); + + /** + * The entity type's numeric network id. + * @param javaId the java id + * @return this builder + */ + @This Builder javaId(int javaId); + + /** + * The width of this entity. + * @param width the width of this entity + * @return this builder + */ + @This Builder width(@NonNegative float width); + + /** + * The height of this entity + * @param height the height + * @return this builder + */ + @This Builder height(@NonNegative float height); + + /** + * The default Bedrock edition entity definition. + * You can define custom Bedrock entities, or use vanilla definitions + * obtainable via the {@link GeyserDefineEntitiesEvent#entities()} collection. + * This entity has to be registered before calling this method! + * + * @param defaultBedrockDefinition the default Bedrock definition + * @return this builder + */ + @This Builder definition(@Nullable GeyserEntityDefinition defaultBedrockDefinition); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/custom/package-info.java b/api/src/main/java/org/geysermc/geyser/api/entity/custom/package-info.java new file mode 100644 index 00000000000..30ed743b1c6 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/custom/package-info.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +@NullMarked +package org.geysermc.geyser.api.entity.custom; + +import org.jspecify.annotations.NullMarked; diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserEntityDataType.java b/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserEntityDataType.java new file mode 100644 index 00000000000..3484f217bf4 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserEntityDataType.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.data; + +import org.geysermc.geyser.api.GeyserApi; +import org.geysermc.geyser.api.entity.type.GeyserEntity; + +/** + * Represents a type of entity data that can be sent for an entity. + *

+ * Entity data types define the kind of value stored for a particular piece of metadata, + * such as a {@code Byte}, {@code Integer}, {@code Float}; and the name associated with them. + *

+ * Unlike custom items or blocks, it is possible to update entity metadata at runtime, + * which can be done using {@link GeyserEntity#update(GeyserEntityDataType, Object)}. + * + * @param the value type associated with this entity data type + */ +public interface GeyserEntityDataType { + + /** + * Gets the Java class representing the value type associated with this data type. + * + * @return the class of the value used by this entity data type + */ + Class typeClass(); + + /** + * Gets the unique name of this data type. + *

+ * The name is used internally to identify and register the data type so it can be + * referenced when reading or writing entity metadata. + * + * @return the name of this entity data type + */ + String name(); + + /** + * For API usage only; use the types defined in {@link GeyserEntityDataTypes} + */ + static GeyserEntityDataType of(Class typeClass, String name) { + return GeyserApi.api().provider(GeyserEntityDataType.class, typeClass, name); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserEntityDataTypes.java b/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserEntityDataTypes.java new file mode 100644 index 00000000000..e526d0f74c1 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserEntityDataTypes.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.data; + +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.api.entity.data.types.Hitbox; + +/** + * Contains commonly used {@link GeyserEntityDataType} constants for built-in entity + * metadata fields. + *

+ * These data types define the structure of certain primitive or numeric metadata + * values that can be used for Bedrock entities. Each constant is backed by a + * pre-registered entity data type that can be used when reading or writing metadata + * through the Geyser API. + */ +public final class GeyserEntityDataTypes { + + /** + * Represents a single-byte value used for color types + * (e.g., sheep wool color). + */ + public static final GeyserEntityDataType COLOR = + GeyserEntityDataType.of(Byte.class, "color"); + + /** + * Represents a numeric variant index that can be queried in resource packs. + */ + public static final GeyserEntityDataType VARIANT = + GeyserEntityDataType.of(Integer.class, "variant"); + + /** + * Represents the entity's width. + */ + public static final GeyserEntityDataType WIDTH = + GeyserEntityDataType.of(Float.class, "width"); + + /** + * Represents the entity's height. + */ + public static final GeyserEntityDataType HEIGHT = + GeyserEntityDataType.of(Float.class, "height"); + + /** + * Represents the entity's vertical offset. + */ + public static final GeyserEntityDataType VERTICAL_OFFSET = + GeyserEntityDataType.of(Float.class, "vertical_offset"); + + /** + * Represents the scale multiplier. + */ + public static final GeyserEntityDataType SCALE = + GeyserEntityDataType.of(Float.class, "scale"); + + /** + * Represents custom hitboxes for entities + */ + public static final GeyserListEntityDataType HITBOXES = + GeyserListEntityDataType.of(Hitbox.class, "hitboxes"); + + /** + * Represents the entity's seat offset. Applied when mounting an entity. + * Note: This can get overridden when a new entity is mounted, in which case, the seat offset + * would need to be updated again! + */ + public static final GeyserEntityDataType SEAT_OFFSET = + GeyserEntityDataType.of(Vector3f.class, "seat_offset"); + + private GeyserEntityDataTypes() { + // no-op + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserListEntityDataType.java b/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserListEntityDataType.java new file mode 100644 index 00000000000..cf60351fecd --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/data/GeyserListEntityDataType.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.data; + +import org.geysermc.geyser.api.GeyserApi; + +import java.util.List; + +/** + * Represents a list of objects for specific entity data types. + * For example, there can be multiple hitboxes on an entity. + * + * @param the object type in the list + */ +public interface GeyserListEntityDataType extends GeyserEntityDataType> { + + /** + * @return the class of the list entries + */ + Class listEntryClass(); + + /** + * API usage only, use the types defined in {@link GeyserEntityDataTypes} + */ + static GeyserListEntityDataType of(Class typeClass, String name) { + return GeyserApi.api().provider(GeyserListEntityDataType.class, List.class, typeClass, name); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/data/package-info.java b/api/src/main/java/org/geysermc/geyser/api/entity/data/package-info.java new file mode 100644 index 00000000000..4111ccac8d6 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/data/package-info.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +@NullMarked +package org.geysermc.geyser.api.entity.data; + +import org.jspecify.annotations.NullMarked; diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/data/types/Hitbox.java b/api/src/main/java/org/geysermc/geyser/api/entity/data/types/Hitbox.java new file mode 100644 index 00000000000..4861d3101b9 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/data/types/Hitbox.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.data.types; + +import org.checkerframework.common.returnsreceiver.qual.This; +import org.cloudburstmc.math.vector.Vector3f; +import org.geysermc.geyser.api.GeyserApi; + +/** + * Represents an entity hitbox. + */ +public interface Hitbox { + + /** + * Represents an empty / disabled hitbox. + */ + Hitbox EMPTY = GeyserApi.api().provider(Hitbox.class, true); + + /** + * The min "corner" of the hitbox + * @return the vector of the corner + */ + Vector3f min(); + + /** + * The max "corner" of the hitbox + * @return the vector of the corner + */ + Vector3f max(); + + /** + * The pivot of the hitbox + * @return the pivot + */ + Vector3f pivot(); + + static Builder builder() { + return GeyserApi.api().provider(Builder.class); + } + + /** + * The builder for the hitbox + */ + interface Builder { + + /** + * Sets the min corner of the hitbox + * @param min the vector of the corner + * @return this builder + */ + @This Builder min(Vector3f min); + + /** + * Sets the max corner of the hitbox + * @param max the vector of the corner + * @return this builder + */ + @This Builder max(Vector3f max); + + /** + * Sets the pivot of the hitbox + * @param pivot the pivot vector + * @return this builder + */ + @This Builder pivot(Vector3f pivot); + + /** + * Builds this hitbox, defaulting to {@code Vector3f.ZERO} if + * any one vector was not provided. + * + * @return a new hitbox + */ + Hitbox build(); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/data/types/package-info.java b/api/src/main/java/org/geysermc/geyser/api/entity/data/types/package-info.java new file mode 100644 index 00000000000..13e48938f5f --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/data/types/package-info.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +@NullMarked +package org.geysermc.geyser.api.entity.data.types; + +import org.jspecify.annotations.NullMarked; diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/definition/GeyserEntityDefinition.java b/api/src/main/java/org/geysermc/geyser/api/entity/definition/GeyserEntityDefinition.java new file mode 100644 index 00000000000..e6d5ade143f --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/definition/GeyserEntityDefinition.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.definition; + +import org.geysermc.geyser.api.GeyserApi; +import org.geysermc.geyser.api.entity.property.GeyserEntityProperty; +import org.geysermc.geyser.api.event.lifecycle.GeyserDefineEntitiesEvent; +import org.geysermc.geyser.api.util.Identifier; + +import java.util.List; + +/** + * Represents a Bedrock entity definition. + * Custom Bedrock entity definitions must be registered in the + * {@link GeyserDefineEntitiesEvent} before usage! + */ +public interface GeyserEntityDefinition { + + /** + * @return the Bedrock entity identifier + */ + Identifier identifier(); + + /** + * @return the properties registered for this entity type + */ + List> properties(); + + /** + * @return whether this entity is a vanilla entity + */ + boolean vanilla(); + + /** + * @return whether this definition has been registered + */ + boolean registered(); + + /** + * Creates or retrieves a GeyserEntityDefinition by the Bedrock entity type identifier. + * + * @param identifier the Bedrock entity identifier + * @return the GeyserEntityDefinition + */ + static GeyserEntityDefinition of(Identifier identifier) { + return GeyserApi.api().provider(GeyserEntityDefinition.class, identifier); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/definition/JavaEntityType.java b/api/src/main/java/org/geysermc/geyser/api/entity/definition/JavaEntityType.java new file mode 100644 index 00000000000..1b0d245983b --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/definition/JavaEntityType.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.entity.definition; + +import org.geysermc.geyser.api.util.Identifier; +import org.jspecify.annotations.Nullable; + +/** + * Represents a Java edition entity type + */ +public interface JavaEntityType { + + /** + * @return the Java identifier of the type + */ + Identifier identifier(); + + /** + * @return the numeric Java entity type id + */ + int javaId(); + + /** + * @return whether this entity exists in the vanilla base game + */ + boolean vanilla(); + + /** + * @return the width of the Java entity + */ + float width(); + + /** + * @return the height of the Java entity + */ + float height(); + + /** + * Compares two entity identifiers. + * + * @param javaIdentifier the other entity identifier + * @return true if the entity identifier is the same + */ + default boolean is(Identifier javaIdentifier) { + return identifier().equals(javaIdentifier); + } + + /** + * Gets the default Bedrock entity definition, if available, + * that is associated with this Minecraft: Java Edition entity type. + * + * @return the default Bedrock entity definition + */ + @Nullable GeyserEntityDefinition defaultBedrockDefinition(); +} diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/definition/package-info.java b/api/src/main/java/org/geysermc/geyser/api/entity/definition/package-info.java new file mode 100644 index 00000000000..3ccab92d450 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/entity/definition/package-info.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +@NullMarked +package org.geysermc.geyser.api.entity.definition; + +import org.jspecify.annotations.NullMarked; diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/type/GeyserEntity.java b/api/src/main/java/org/geysermc/geyser/api/entity/type/GeyserEntity.java index 922c87491a8..9f923e2d216 100644 --- a/api/src/main/java/org/geysermc/geyser/api/entity/type/GeyserEntity.java +++ b/api/src/main/java/org/geysermc/geyser/api/entity/type/GeyserEntity.java @@ -26,12 +26,19 @@ package org.geysermc.geyser.api.entity.type; import org.checkerframework.checker.index.qual.NonNegative; +import org.checkerframework.checker.index.qual.Positive; +import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.entity.data.GeyserEntityDataType; +import org.geysermc.geyser.api.entity.data.GeyserEntityDataTypes; +import org.geysermc.geyser.api.entity.definition.GeyserEntityDefinition; import org.geysermc.geyser.api.entity.property.BatchPropertyUpdater; import org.geysermc.geyser.api.entity.property.GeyserEntityProperty; import org.geysermc.geyser.api.event.lifecycle.GeyserDefineEntityPropertiesEvent; import org.jspecify.annotations.Nullable; +import java.util.List; +import java.util.UUID; import java.util.function.Consumer; /** @@ -40,11 +47,68 @@ */ public interface GeyserEntity { /** - * @return the entity ID that the server has assigned to this entity. + * @return the entity ID that the server has assigned to this entity, or 0 if none is present */ @NonNegative int javaId(); + /** + * @return the Geyser entity id that the Bedrock client sees + */ + @Positive + long geyserId(); + + /** + * @return the entity uuid that the server has assigned to this entity, + * or null if none is assigned + */ + @Nullable + UUID uuid(); + + /** + * @return the Bedrock entity definition + */ + GeyserEntityDefinition definition(); + + /** + * The position of this entity, without the Bedrock edition offset + * defined in the Bedrock entity definition. + * + * @return the position of the entity, as it is known to the Java server. + */ + Vector3f position(); + + /** + * The vehicle this entity is currently on, or null if not present. + */ + @Nullable + GeyserEntity vehicle(); + + /** + * The passengers of this entity, or an empty list if none are present. + */ + List passengers(); + + /** + * Queries the current value of a given {@link GeyserEntityDataType}. + * + * @see GeyserEntityDataTypes + * @param dataType the entity data type to query + * @return the value, or null if not set + * @param the type of the value + */ + @Nullable T value(GeyserEntityDataType dataType); + + /** + * Updates an entity property with a new value. + * If the new value is null, the property is reset to the default value. + * + * @param dataType an entity data type, such as from {@link GeyserEntityDataTypes} + * @param value the new property value + * @param the type of the value + */ + void update(GeyserEntityDataType dataType, @Nullable T value); + /** * Updates an entity property with a new value. * If the new value is null, the property is reset to the default value. @@ -59,12 +123,9 @@ default void updateProperty(GeyserEntityProperty property, @Nullable T va } /** - * Updates multiple properties with just one update packet. - * @see BatchPropertyUpdater - * - * @param consumer a batch updater - * @since 2.9.0 + * @deprecated - use {@link #updateProperty(GeyserEntityProperty, Object)} instead */ + @Deprecated default void updatePropertiesBatched(Consumer consumer) { this.updatePropertiesBatched(consumer, false); } @@ -73,10 +134,10 @@ default void updatePropertiesBatched(Consumer consumer) { * Updates multiple properties with just one update packet, which can be sent immediately to the client. * Usually, sending updates immediately is not required except for specific situations where packet batching * would result in update order issues. - * @see BatchPropertyUpdater * * @param consumer a batch updater * @param immediate whether this update should be sent immediately + * @see BatchPropertyUpdater * @since 2.9.1 */ void updatePropertiesBatched(Consumer consumer, boolean immediate); diff --git a/api/src/main/java/org/geysermc/geyser/api/entity/type/player/GeyserPlayerEntity.java b/api/src/main/java/org/geysermc/geyser/api/entity/type/player/GeyserPlayerEntity.java index d31def99670..da2e286090b 100644 --- a/api/src/main/java/org/geysermc/geyser/api/entity/type/player/GeyserPlayerEntity.java +++ b/api/src/main/java/org/geysermc/geyser/api/entity/type/player/GeyserPlayerEntity.java @@ -25,15 +25,7 @@ package org.geysermc.geyser.api.entity.type.player; -import org.cloudburstmc.math.vector.Vector3f; import org.geysermc.geyser.api.entity.type.GeyserEntity; public interface GeyserPlayerEntity extends GeyserEntity { - - /** - * Gets the position of the player, as it is known to the Java server. - * - * @return the player's position - */ - Vector3f position(); } diff --git a/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSpawnEntityEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSpawnEntityEvent.java new file mode 100644 index 00000000000..8feda193da3 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/bedrock/SessionSpawnEntityEvent.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.bedrock; + +import org.geysermc.event.Cancellable; +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.entity.definition.GeyserEntityDefinition; +import org.geysermc.geyser.api.entity.type.GeyserEntity; +import org.geysermc.geyser.api.event.connection.ConnectionEvent; +import org.geysermc.geyser.api.event.java.ServerAttachParrotsEvent; +import org.geysermc.geyser.api.event.java.ServerSpawnEntityEvent; +import org.geysermc.geyser.api.event.lifecycle.GeyserDefineEntitiesEvent; +import org.jspecify.annotations.Nullable; + +import java.util.function.Consumer; + +/** + * See {@link ServerSpawnEntityEvent} and {@link ServerAttachParrotsEvent} + */ +public abstract class SessionSpawnEntityEvent extends ConnectionEvent implements Cancellable { + + public SessionSpawnEntityEvent(GeyserConnection connection) { + super(connection); + } + + /** + * Gets the entity definition sent to the connection when the entity is spawned. + * + * @return the entity definition sent to the connection when the entity is spawned + */ + public abstract @Nullable GeyserEntityDefinition definition(); + + /** + * Sets the entity definition sent to the connection when the entity is spawned. + * This entity definition MUST have been registered in the {@link GeyserDefineEntitiesEvent} before + * using it here! + * + * @param entityDefinition the entity definition sent to the connection when the entity is spawned + */ + public abstract void definition(@Nullable GeyserEntityDefinition entityDefinition); + + /** + * Adds a consumer for the {@link GeyserEntity} that will be called once the entity is created, + * assuming that it hasn't been cancelled. + * Using this method, you can modify the entities' entity properties, scale, with, and other entity data. + * + * @param consumer the consumer for the new GeyserEntity + */ + public abstract void preSpawnConsumer(Consumer consumer); +} diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerAttachParrotsEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerAttachParrotsEvent.java new file mode 100644 index 00000000000..6d4c9fb0949 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerAttachParrotsEvent.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.java; + +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity; +import org.geysermc.geyser.api.event.bedrock.SessionSpawnEntityEvent; + +/** + * Called when the Java server attaches parrots to a player. + */ +public abstract class ServerAttachParrotsEvent extends SessionSpawnEntityEvent { + + public ServerAttachParrotsEvent(GeyserConnection connection) { + super(connection); + } + + /** + * @return the player with bird friends + */ + public abstract GeyserPlayerEntity player(); + + /** + * @return the parrot variant + */ + public abstract int variant(); + + /** + * @return true if parrot is on the right shoulder, left otherwise + */ + public abstract boolean right(); +} diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerSpawnEntityEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerSpawnEntityEvent.java new file mode 100644 index 00000000000..338f3faa9a4 --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerSpawnEntityEvent.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.java; + +import org.geysermc.event.Cancellable; +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.entity.definition.JavaEntityType; +import org.geysermc.geyser.api.event.bedrock.SessionSpawnEntityEvent; + +import java.util.UUID; + +/** + * Called when the downstream server spawns a non-player entity. + */ +public abstract class ServerSpawnEntityEvent extends SessionSpawnEntityEvent implements Cancellable { + + public ServerSpawnEntityEvent(GeyserConnection connection) { + super(connection); + } + + /** + * Gets the entity id of the entity being spawned. + * + * @return the entity id of the entity being spawned + */ + public abstract int entityId(); + + /** + * Gets the uuid of the entity being spawned. + * + * @return the uuid of the entity being spawned + */ + public abstract UUID uuid(); + + /** + * Gets the Java entity type sent by the server + * + * @return the Java edition entity type of the entity being spawned + */ + public abstract JavaEntityType entityType(); +} diff --git a/api/src/main/java/org/geysermc/geyser/api/event/java/ServerUpdateEntityPassengersEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerUpdateEntityPassengersEvent.java new file mode 100644 index 00000000000..21c299e46aa --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/java/ServerUpdateEntityPassengersEvent.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2026 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.java; + +import org.geysermc.geyser.api.connection.GeyserConnection; +import org.geysermc.geyser.api.entity.type.GeyserEntity; +import org.geysermc.geyser.api.event.connection.ConnectionEvent; + +/** + * This event is called when an entity's passengers are updated. + * To avoid de-syncs, you cannot cancel this event. + */ +public abstract class ServerUpdateEntityPassengersEvent extends ConnectionEvent { + + /** + * The vehicle entity that gets a passenger update. + * + * @return the vehicle entity + */ + public abstract GeyserEntity vehicle(); + + public ServerUpdateEntityPassengersEvent(GeyserConnection connection) { + super(connection); + } + + public abstract static class Mount extends ServerUpdateEntityPassengersEvent { + public Mount(GeyserConnection connection) { + super(connection); + } + + /** + * @return the passenger that was added to the vehicle + */ + public abstract GeyserEntity addedPassenger(); + } + + public abstract static class Dismount extends ServerUpdateEntityPassengersEvent { + public Dismount(GeyserConnection connection) { + super(connection); + } + + /** + * @return the passenger that was removed from the vehicle + */ + public abstract GeyserEntity removedPassenger(); + } +} diff --git a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntitiesEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntitiesEvent.java new file mode 100644 index 00000000000..80bb9183bdb --- /dev/null +++ b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntitiesEvent.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.api.event.lifecycle; + +import org.geysermc.event.Event; +import org.geysermc.geyser.api.entity.custom.CustomEntityDefinition; +import org.geysermc.geyser.api.entity.custom.CustomJavaEntityType; +import org.geysermc.geyser.api.entity.definition.GeyserEntityDefinition; + +import java.util.Collection; +import java.util.function.Consumer; + +/** + * Called when entities are defined within Geyser. + *

+ * This event can be used to add custom entities to Geyser. + */ +public interface GeyserDefineEntitiesEvent extends Event { + + /** + * @return an immutable collection of all registered entity definitions + */ + Collection entities(); + + /** + * @return an immutable collection of all registered custom entity definitions + */ + Collection customEntities(); + + /** + * Registers a custom entity definition + * @param definition the custom entity definition to register + */ + void register(CustomEntityDefinition definition); + + /** + * Registers a non-vanilla Java entity type. + * + * @param builderConsumer the builder for the non-vanilla type + */ + void registerEntityType(Consumer builderConsumer); +} diff --git a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntityPropertiesEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntityPropertiesEvent.java index 1230e3551fe..d50054d2741 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntityPropertiesEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineEntityPropertiesEvent.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.api.event.lifecycle; import org.geysermc.event.Event; +import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.entity.EntityData; import org.geysermc.geyser.api.entity.property.GeyserEntityProperty; import org.geysermc.geyser.api.entity.property.type.GeyserBooleanEntityProperty; @@ -39,7 +40,6 @@ import java.util.Collection; import java.util.List; -import java.util.function.Consumer; /** * Lifecycle event fired during Geyser's startup to allow custom entity properties @@ -61,10 +61,9 @@ * } * } * - * Retrieving entity instances is possible with the {@link EntityData#entityByJavaId(int)} method, or - * {@link EntityData#playerEntity()} for the connection player entity. - * To update the value of a property on a specific entity, use {@link GeyserEntity#updateProperty(GeyserEntityProperty, Object)}, - * or {@link GeyserEntity#updatePropertiesBatched(Consumer)} to update multiple properties efficiently at once. + * Retrieving entity instances is possible with, for example, the {@link EntityData#byJavaId(int)} method, or + * {@link GeyserConnection#playerEntity()} for the connection player entity. + * To update the value of a property on a specific entity, use {@link GeyserEntity#updateProperty(GeyserEntityProperty, Object)}. * *

Notes: *