mirror of https://github.com/GeyserMC/Geyser.git
Compare commits
87 Commits
2a793ce8e7
...
c6c9bd76f7
Author | SHA1 | Date |
---|---|---|
James E. A | c6c9bd76f7 | |
basaigh | 9d299ee83b | |
basaigh | a39cd65537 | |
Camotoy | b39ed5de53 | |
Camotoy | cab1a20034 | |
Camotoy | 6a214f235c | |
Camotoy | efda13421f | |
onebeastchris | f7c65f38d1 | |
AJ Ferguson | 60f8532be3 | |
AJ Ferguson | 29a613b85c | |
AJ Ferguson | d003818e73 | |
AJ Ferguson | fdae333351 | |
Camotoy | cc635d4447 | |
Camotoy | 1e8d6b23cf | |
Camotoy | abb1d7d9e9 | |
Camotoy | 59a2c0dc02 | |
AJ Ferguson | aff7d2cf35 | |
onebeastchris | 255835438d | |
onebeastchris | 51cbbba47c | |
onebeastchris | 4a0a694eb9 | |
onebeastchris | d99f498901 | |
onebeastchris | dd745b901f | |
AJ Ferguson | ff9965f559 | |
AJ Ferguson | 74d6a37261 | |
AJ Ferguson | dacacc6df8 | |
Camotoy | c963503fef | |
onebeastchris | 28d5db622b | |
onebeastchris | 5d3630cf23 | |
onebeastchris | 8b7b8cdffd | |
AJ Ferguson | 4ff746e48a | |
Camotoy | a82a156419 | |
Camotoy | 88ae447fc6 | |
Camotoy | e8c1c2218f | |
onebeastchris | 82123aecf1 | |
onebeastchris | 8ab0921448 | |
onebeastchris | 9b1e45007a | |
basaigh | 420f67752c | |
AJ Ferguson | e97bbcc483 | |
Camotoy | 6d5ac233d6 | |
Camotoy | f47754be03 | |
Camotoy | 9217414c8c | |
Camotoy | 2fa7585db3 | |
onebeastchris | 5015a2ef89 | |
onebeastchris | 68534f386c | |
onebeastchris | f67c131b8d | |
onebeastchris | 91a74603c7 | |
AJ Ferguson | 3656395ce1 | |
onebeastchris | 8e3a3ea453 | |
onebeastchris | 16cb76f523 | |
Joshua Castle | 99e6a2981d | |
Joshua Castle | 652f6af784 | |
Camotoy | 9d540fe672 | |
Camotoy | b29e0d9d10 | |
AJ Ferguson | 9490a091b5 | |
Camotoy | a1534e4535 | |
AJ Ferguson | bbaffb2ab3 | |
onebeastchris | 687d299ff5 | |
Camotoy | c54624fb26 | |
Camotoy | abea0131e4 | |
Camotoy | d105dadf62 | |
Camotoy | b81408820b | |
onebeastchris | c48428daf0 | |
AJ Ferguson | 9d8edad9fc | |
Joshua Castle | 3f499e3ec0 | |
AJ Ferguson | 1bdbcab4e8 | |
AJ Ferguson | d3f902ae34 | |
Camotoy | 11f79d4e2c | |
onebeastchris | 6a5efa3c9d | |
Camotoy | c34f0f2c3b | |
basaigh | dac5f69d47 | |
AJ Ferguson | 8381a148fc | |
onebeastchris | c5e02d28e6 | |
basaigh | 48164e93c7 | |
onebeastchris | b73f23de0f | |
basaigh | 57ce5706ee | |
Camotoy | 61907b1851 | |
Camotoy | 687ddbb520 | |
AJ Ferguson | ab8832b771 | |
Camotoy | 8bd2df0828 | |
basaigh | 94e533ea7c | |
Camotoy | aed7f1bed7 | |
basaigh | 6d8021f155 | |
Camotoy | 909139326d | |
Camotoy | c1edf20734 | |
Camotoy | 099e968bde | |
James Edington | 8d2db2e4e2 | |
James Edington | d2c2dd54e4 |
|
@ -0,0 +1,2 @@
|
|||
.dockerignore
|
||||
*Dockerfile
|
|
@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
|||
|
||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
||||
|
||||
### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4
|
||||
### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.5/1.20.6
|
||||
|
||||
## Setting Up
|
||||
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
||||
|
|
|
@ -32,6 +32,9 @@ import org.geysermc.geyser.api.connection.GeyserConnection;
|
|||
import org.geysermc.geyser.api.event.connection.ConnectionEvent;
|
||||
import org.geysermc.geyser.api.network.RemoteServer;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Called when a session has logged in, and is about to connect to a remote java server.
|
||||
* This event is cancellable, and can be used to prevent the player from connecting to the remote server.
|
||||
|
@ -40,10 +43,16 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella
|
|||
private RemoteServer remoteServer;
|
||||
private boolean cancelled;
|
||||
private String disconnectReason;
|
||||
private Map<String, byte[]> cookies;
|
||||
private boolean transferring;
|
||||
|
||||
public SessionLoginEvent(@NonNull GeyserConnection connection, @NonNull RemoteServer remoteServer) {
|
||||
public SessionLoginEvent(@NonNull GeyserConnection connection,
|
||||
@NonNull RemoteServer remoteServer,
|
||||
@NonNull Map<String, byte[]> cookies) {
|
||||
super(connection);
|
||||
this.remoteServer = remoteServer;
|
||||
this.cookies = cookies;
|
||||
this.transferring = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,4 +115,36 @@ public final class SessionLoginEvent extends ConnectionEvent implements Cancella
|
|||
public void remoteServer(@NonNull RemoteServer remoteServer) {
|
||||
this.remoteServer = remoteServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a map of cookies from a possible previous session. The Java server can send and request these
|
||||
* to store information on the client across server transfers.
|
||||
*/
|
||||
public void cookies(@NonNull Map<String, byte[]> cookies) {
|
||||
Objects.requireNonNull(cookies);
|
||||
this.cookies = cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of the sessions cookies, if set.
|
||||
* @return the connections cookies
|
||||
*/
|
||||
public @NonNull Map<String, byte[]> cookies() {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the connection intent of the connection
|
||||
*/
|
||||
public void transferring(boolean transferring) {
|
||||
this.transferring = transferring;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this login attempt to the Java server
|
||||
* has the transfer intent
|
||||
*/
|
||||
public boolean transferring() {
|
||||
return this.transferring;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.common.value.qual.IntRange;
|
||||
import org.geysermc.geyser.api.connection.GeyserConnection;
|
||||
import org.geysermc.geyser.api.event.connection.ConnectionEvent;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Fired when the Java server sends a transfer request to a different Java server.
|
||||
* Geyser Extensions can listen to this event and set a target server ip/port for Bedrock players to be transferred to.
|
||||
*/
|
||||
public class ServerTransferEvent extends ConnectionEvent {
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
private String bedrockHost;
|
||||
private int bedrockPort;
|
||||
private final Map<String, byte[]> cookies;
|
||||
|
||||
public ServerTransferEvent(@NonNull GeyserConnection connection,
|
||||
@NonNull String host, int port, @NonNull Map<String, byte[]> cookies) {
|
||||
super(connection);
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.cookies = cookies;
|
||||
this.bedrockHost = null;
|
||||
this.bedrockPort = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The host that the Java server requests a transfer to.
|
||||
*
|
||||
* @return the host
|
||||
*/
|
||||
public @NonNull String host() {
|
||||
return this.host;
|
||||
}
|
||||
|
||||
/**
|
||||
* The port that the Java server requests a transfer to.
|
||||
*
|
||||
* @return the port
|
||||
*/
|
||||
public int port() {
|
||||
return this.port;
|
||||
}
|
||||
|
||||
/**
|
||||
* The host that the Bedrock player should try and connect to.
|
||||
* If this is not set, the Bedrock player will just be disconnected.
|
||||
*
|
||||
* @return the host where the Bedrock client will be transferred to, or null if not set.
|
||||
*/
|
||||
public @Nullable String bedrockHost() {
|
||||
return this.bedrockHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* The port that the Bedrock player should try and connect to.
|
||||
* If this is not set, the Bedrock player will just be disconnected.
|
||||
*
|
||||
* @return the port where the Bedrock client will be transferred to, or -1 if not set.
|
||||
*/
|
||||
public int bedrockPort() {
|
||||
return this.bedrockPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host for the Bedrock player to be transferred to
|
||||
*/
|
||||
public void bedrockHost(@NonNull String host) {
|
||||
if (host == null || host.isBlank()) {
|
||||
throw new IllegalArgumentException("Server address cannot be null or blank");
|
||||
}
|
||||
this.bedrockHost = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the port for the Bedrock player to be transferred to
|
||||
*/
|
||||
public void bedrockPort(@IntRange(from = 0, to = 65535) int port) {
|
||||
if (port < 0 || port > 65535) {
|
||||
throw new IllegalArgumentException("Server port must be between 0 and 65535, was " + port);
|
||||
}
|
||||
this.bedrockPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of the sessions current cookies.
|
||||
*
|
||||
* @return the connections cookies
|
||||
*/
|
||||
public @NonNull Map<String, byte[]> cookies() {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
}
|
|
@ -49,9 +49,7 @@ application {
|
|||
|
||||
relocate("org.cloudburstmc.netty")
|
||||
relocate("org.cloudburstmc.protocol")
|
||||
relocate("com.github.steveice10.mc.protocol")
|
||||
relocate("com.github.steveice10.mc.auth")
|
||||
relocate("com.github.steveice10.packetlib")
|
||||
|
||||
tasks {
|
||||
remapJar {
|
||||
|
|
|
@ -23,9 +23,8 @@
|
|||
"geyser.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.15.2",
|
||||
"fabricloader": ">=0.15.10",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=1.20.4",
|
||||
"fabric-permissions-api-v0": "*"
|
||||
"minecraft": ">=1.20.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,12 @@ config = "geyser.mixins.json"
|
|||
[[dependencies.geyser_neoforge]]
|
||||
modId="neoforge"
|
||||
type="required"
|
||||
versionRange="[20.4.48-beta,)"
|
||||
versionRange="[20.5.0-beta,)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
[[dependencies.geyser_neoforge]]
|
||||
modId="minecraft"
|
||||
type="required"
|
||||
versionRange="[1.20,1.21)"
|
||||
versionRange="[1.20.5,1.21)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
|
@ -243,6 +243,11 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
return ip != null ? ip : ""; // See issue #3812
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress getSocketAddress() {
|
||||
return this.geyserInjector.getServerSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerPort() {
|
||||
if (isServer()) {
|
||||
|
@ -255,11 +260,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
|
||||
public abstract boolean isServer();
|
||||
|
||||
@Override
|
||||
public @Nullable SocketAddress getSocketAddress() {
|
||||
return this.geyserInjector.getServerSocketAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testFloodgatePluginPresent() {
|
||||
return this.platform.testFloodgatePluginPresent(this);
|
||||
|
|
|
@ -93,8 +93,11 @@ public class GeyserModInjector extends GeyserInjector {
|
|||
protected void initChannel(@NonNull Channel ch) throws Exception {
|
||||
initChannel.invoke(childHandler, ch);
|
||||
|
||||
int index = ch.pipeline().names().indexOf("encoder");
|
||||
String baseName = index != -1 ? "encoder" : "outbound_config";
|
||||
|
||||
if (bootstrap.getGeyserConfig().isDisableCompression()) {
|
||||
ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserModCompressionDisabler());
|
||||
ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserModCompressionDisabler());
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -29,6 +29,7 @@ import lombok.AllArgsConstructor;
|
|||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.PacketSendListener;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
|
@ -69,7 +70,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough {
|
|||
StatusInterceptor connection = new StatusInterceptor();
|
||||
ServerStatusPacketListener statusPacketListener = new ServerStatusPacketListenerImpl(status, connection);
|
||||
|
||||
statusPacketListener.handleStatusRequest(new ServerboundStatusRequestPacket());
|
||||
statusPacketListener.handleStatusRequest(ServerboundStatusRequestPacket.INSTANCE);
|
||||
// mods like MiniMOTD (that inject into the above method) have now processed the response
|
||||
status = Objects.requireNonNull(connection.status, "status response");
|
||||
} catch (Exception e) {
|
||||
|
@ -79,7 +80,7 @@ public class ModPingPassthrough implements IGeyserPingPassthrough {
|
|||
}
|
||||
}
|
||||
|
||||
String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description());
|
||||
String jsonDescription = net.minecraft.network.chat.Component.Serializer.toJson(status.description(), RegistryAccess.EMPTY);
|
||||
String legacyDescription = LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(jsonDescription, Component.empty()));
|
||||
|
||||
return new GeyserPingInfo(
|
||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.mod.command;
|
|||
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
@ -63,7 +64,7 @@ public class ModCommandSender implements GeyserCommandSource {
|
|||
public void sendMessage(net.kyori.adventure.text.Component message) {
|
||||
if (source.getEntity() instanceof ServerPlayer player) {
|
||||
String decoded = GsonComponentSerializer.gson().serialize(message);
|
||||
player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded)), false);
|
||||
player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded, RegistryAccess.EMPTY)), false);
|
||||
return;
|
||||
}
|
||||
GeyserCommandSource.super.sendMessage(message);
|
||||
|
|
|
@ -25,39 +25,34 @@
|
|||
|
||||
package org.geysermc.geyser.platform.mod.world;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.EndTag;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
import net.minecraft.nbt.IntArrayTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.LongArrayTag;
|
||||
import net.minecraft.nbt.LongTag;
|
||||
import net.minecraft.nbt.ShortTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.nbt.TagVisitor;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.Filterable;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.WritableBookItem;
|
||||
import net.minecraft.world.item.WrittenBookItem;
|
||||
import net.minecraft.world.item.component.WritableBookContent;
|
||||
import net.minecraft.world.item.component.WrittenBookContent;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BannerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BannerPatternLayers;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -71,11 +66,14 @@ import org.geysermc.geyser.session.GeyserSession;
|
|||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class GeyserModWorldManager extends GeyserWorldManager {
|
||||
|
||||
private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson();
|
||||
private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection();
|
||||
private final MinecraftServer server;
|
||||
|
||||
public GeyserModWorldManager(MinecraftServer server) {
|
||||
|
@ -180,7 +178,7 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
|||
}
|
||||
|
||||
ItemStack book = lectern.getBook();
|
||||
int pageCount = WrittenBookItem.getPageCount(book);
|
||||
int pageCount = getPageCount(book);
|
||||
boolean hasBookPages = pageCount > 0;
|
||||
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x, y, z, hasBookPages ? pageCount : 1);
|
||||
lecternTag.putInt("page", lectern.getPage() / 2);
|
||||
|
@ -189,11 +187,9 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
|||
.putShort("Damage", (short) 0)
|
||||
.putString("Name", "minecraft:writable_book");
|
||||
List<NbtMap> pages = new ArrayList<>(hasBookPages ? pageCount : 1);
|
||||
if (hasBookPages && WritableBookItem.makeSureTagIsValid(book.getTag())) {
|
||||
ListTag listTag = book.getTag().getList("pages", 8);
|
||||
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
String page = listTag.getString(i);
|
||||
if (hasBookPages) {
|
||||
List<String> bookPages = getPages(book);
|
||||
for (String page : bookPages) {
|
||||
NbtMapBuilder pageBuilder = NbtMap.builder()
|
||||
.putString("photoname", "")
|
||||
.putString("text", page);
|
||||
|
@ -226,8 +222,8 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
|||
|
||||
@NonNull
|
||||
@Override
|
||||
public CompletableFuture<com.github.steveice10.opennbt.tag.builtin.CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) {
|
||||
CompletableFuture<com.github.steveice10.opennbt.tag.builtin.CompoundTag> future = new CompletableFuture<>();
|
||||
public CompletableFuture<org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) {
|
||||
CompletableFuture<org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents> future = new CompletableFuture<>();
|
||||
server.execute(() -> {
|
||||
ServerPlayer player = getPlayer(session);
|
||||
if (player == null) {
|
||||
|
@ -243,9 +239,23 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
|||
// Potentially exposes other NBT data? But we need to get the NBT data for the banner patterns *and*
|
||||
// the banner might have a custom name, both of which a Java client knows and caches
|
||||
ItemStack itemStack = banner.getItem();
|
||||
var tag = OpenNbtTagVisitor.convert("", itemStack.getOrCreateTag());
|
||||
|
||||
future.complete(tag);
|
||||
org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents components =
|
||||
new org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents(new HashMap<>());
|
||||
|
||||
components.put(DataComponentType.DAMAGE, itemStack.getDamageValue());
|
||||
|
||||
Component customName = itemStack.getComponents().get(DataComponents.CUSTOM_NAME);
|
||||
if (customName != null) {
|
||||
components.put(DataComponentType.CUSTOM_NAME, toKyoriComponent(customName));
|
||||
}
|
||||
|
||||
BannerPatternLayers pattern = itemStack.get(DataComponents.BANNER_PATTERNS);
|
||||
if (pattern != null) {
|
||||
components.put(DataComponentType.BANNER_PATTERNS, toPatternList(pattern));
|
||||
}
|
||||
|
||||
future.complete(components);
|
||||
return;
|
||||
}
|
||||
future.complete(null);
|
||||
|
@ -257,95 +267,52 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
|||
return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid());
|
||||
}
|
||||
|
||||
// Future considerations: option to clone; would affect arrays
|
||||
private static class OpenNbtTagVisitor implements TagVisitor {
|
||||
private String currentKey;
|
||||
private final com.github.steveice10.opennbt.tag.builtin.CompoundTag root;
|
||||
private com.github.steveice10.opennbt.tag.builtin.Tag currentTag;
|
||||
|
||||
OpenNbtTagVisitor(String key) {
|
||||
root = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitString(StringTag stringTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.StringTag(currentKey, stringTag.getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitByte(ByteTag byteTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteTag(currentKey, byteTag.getAsByte());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitShort(ShortTag shortTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.ShortTag(currentKey, shortTag.getAsShort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInt(IntTag intTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.IntTag(currentKey, intTag.getAsInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLong(LongTag longTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.LongTag(currentKey, longTag.getAsLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFloat(FloatTag floatTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.FloatTag(currentKey, floatTag.getAsFloat());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDouble(DoubleTag doubleTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.DoubleTag(currentKey, doubleTag.getAsDouble());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitByteArray(ByteArrayTag byteArrayTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.ByteArrayTag(currentKey, byteArrayTag.getAsByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitIntArray(IntArrayTag intArrayTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.IntArrayTag(currentKey, intArrayTag.getAsIntArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLongArray(LongArrayTag longArrayTag) {
|
||||
currentTag = new com.github.steveice10.opennbt.tag.builtin.LongArrayTag(currentKey, longArrayTag.getAsLongArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitList(ListTag listTag) {
|
||||
var newList = new com.github.steveice10.opennbt.tag.builtin.ListTag(currentKey);
|
||||
for (Tag tag : listTag) {
|
||||
currentKey = "";
|
||||
tag.accept(this);
|
||||
newList.add(currentTag);
|
||||
}
|
||||
currentTag = newList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCompound(@NonNull CompoundTag compoundTag) {
|
||||
currentTag = convert(currentKey, compoundTag);
|
||||
}
|
||||
|
||||
private static com.github.steveice10.opennbt.tag.builtin.CompoundTag convert(String name, CompoundTag compoundTag) {
|
||||
OpenNbtTagVisitor visitor = new OpenNbtTagVisitor(name);
|
||||
for (String key : compoundTag.getAllKeys()) {
|
||||
visitor.currentKey = key;
|
||||
Tag tag = Objects.requireNonNull(compoundTag.get(key));
|
||||
tag.accept(visitor);
|
||||
visitor.root.put(visitor.currentTag);
|
||||
}
|
||||
return visitor.root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd(@NonNull EndTag endTag) {
|
||||
private static int getPageCount(ItemStack itemStack) {
|
||||
WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||||
if (writtenBookContent != null) {
|
||||
return writtenBookContent.pages().size();
|
||||
} else {
|
||||
WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT);
|
||||
return writableBookContent != null ? writableBookContent.pages().size() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> getPages(ItemStack itemStack) {
|
||||
WrittenBookContent writtenBookContent = itemStack.get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||||
if (writtenBookContent != null) {
|
||||
return writtenBookContent.pages().stream()
|
||||
.map(Filterable::raw)
|
||||
.map(GeyserModWorldManager::fromComponent)
|
||||
.toList();
|
||||
} else {
|
||||
WritableBookContent writableBookContent = itemStack.get(DataComponents.WRITABLE_BOOK_CONTENT);
|
||||
if (writableBookContent == null) {
|
||||
return List.of();
|
||||
}
|
||||
return writableBookContent.pages().stream()
|
||||
.map(Filterable::raw)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
private static String fromComponent(Component component) {
|
||||
String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY);
|
||||
return LEGACY_SERIALIZER.serialize(GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty()));
|
||||
}
|
||||
|
||||
private static net.kyori.adventure.text.Component toKyoriComponent(Component component) {
|
||||
String json = Component.Serializer.toJson(component, RegistryAccess.EMPTY);
|
||||
return GSON_SERIALIZER.deserializeOr(json, net.kyori.adventure.text.Component.empty());
|
||||
}
|
||||
|
||||
private static List<BannerPatternLayer> toPatternList(BannerPatternLayers patternLayers) {
|
||||
return patternLayers.layers().stream()
|
||||
.map(layer -> {
|
||||
BannerPatternLayer.BannerPattern pattern = new BannerPatternLayer.BannerPattern(
|
||||
layer.pattern().value().assetId().toString(), layer.pattern().value().translationKey()
|
||||
);
|
||||
return new BannerPatternLayer(Holder.ofCustom(pattern), layer.color().getId());
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ dependencies {
|
|||
implementation(variantOf(libs.adapters.spigot) {
|
||||
classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations
|
||||
})
|
||||
implementation(variantOf(libs.adapters.paper) {
|
||||
classifier("all") // otherwise the unshaded jar is used without the shaded NMS implementations
|
||||
})
|
||||
|
||||
implementation(libs.commodore)
|
||||
|
||||
|
@ -34,6 +37,12 @@ application {
|
|||
}
|
||||
|
||||
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
|
||||
|
||||
// Prevents Paper 1.20.5+ from remapping Geyser
|
||||
manifest {
|
||||
attributes["paperweight-mappings-namespace"] = "mojang"
|
||||
}
|
||||
|
||||
archiveBaseName.set("Geyser-Spigot")
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.platform.spigot;
|
||||
|
||||
import com.github.steveice10.mc.protocol.MinecraftProtocol;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
|
||||
import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.*;
|
||||
|
@ -119,8 +119,11 @@ public class GeyserSpigotInjector extends GeyserInjector {
|
|||
protected void initChannel(@NonNull Channel ch) throws Exception {
|
||||
initChannel.invoke(childHandler, ch);
|
||||
|
||||
int index = ch.pipeline().names().indexOf("encoder");
|
||||
String baseName = index != -1 ? "encoder" : "outbound_config";
|
||||
|
||||
if (bootstrap.getGeyserConfig().isDisableCompression() && GeyserSpigotCompressionDisabler.ENABLED) {
|
||||
ch.pipeline().addAfter("encoder", "geyser-compression-disabler", new GeyserSpigotCompressionDisabler());
|
||||
ch.pipeline().addAfter(baseName, "geyser-compression-disabler", new GeyserSpigotCompressionDisabler());
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -177,6 +180,7 @@ public class GeyserSpigotInjector extends GeyserInjector {
|
|||
bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress,
|
||||
InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper());
|
||||
session.connect();
|
||||
session.disconnect("");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.adapters.paper.PaperAdapters;
|
||||
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
||||
import org.geysermc.geyser.api.command.Command;
|
||||
import org.geysermc.geyser.api.extension.Extension;
|
||||
|
@ -244,16 +245,27 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||
|
||||
if (Boolean.parseBoolean(System.getProperty("Geyser.UseDirectAdapters", "true"))) {
|
||||
try {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
String nmsVersion = name.substring(name.lastIndexOf('.') + 1);
|
||||
SpigotAdapters.registerWorldAdapter(nmsVersion);
|
||||
boolean isPaper = false;
|
||||
try {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
String nmsVersion = name.substring(name.lastIndexOf('.') + 1);
|
||||
SpigotAdapters.registerWorldAdapter(nmsVersion);
|
||||
geyserLogger.debug("Using spigot NMS adapter for nms version: " + nmsVersion);
|
||||
} catch (Exception e) { // Likely running on Paper 1.20.5+
|
||||
//noinspection deprecation
|
||||
int protocolVersion = Bukkit.getUnsafe().getProtocolVersion();
|
||||
PaperAdapters.registerClosestWorldAdapter(protocolVersion);
|
||||
isPaper = true;
|
||||
geyserLogger.debug("Using paper world adapter for protocol version: " + protocolVersion);
|
||||
}
|
||||
|
||||
if (isViaVersion && isViaVersionNeeded()) {
|
||||
this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this);
|
||||
this.geyserWorldManager = new GeyserSpigotLegacyNativeWorldManager(this, isPaper);
|
||||
} else {
|
||||
// No ViaVersion
|
||||
this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this);
|
||||
this.geyserWorldManager = new GeyserSpigotNativeWorldManager(this, isPaper);
|
||||
}
|
||||
geyserLogger.debug("Using NMS adapter: " + this.geyserWorldManager.getClass() + ", " + nmsVersion);
|
||||
geyserLogger.debug("Using world manager of type: " + this.geyserWorldManager.getClass().getSimpleName());
|
||||
} catch (Exception e) {
|
||||
if (geyserConfig.isDebugMode()) {
|
||||
geyserLogger.debug("Error while attempting to find NMS adapter. Most likely, this can be safely ignored. :)");
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.platform.spigot;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.DefaultComponentSerializer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.platform.spigot.world;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.value.PistonValueType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
|
|
|
@ -46,8 +46,8 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl
|
|||
|
||||
private final Int2IntMap oldToNewBlockId;
|
||||
|
||||
public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin) {
|
||||
super(plugin);
|
||||
public GeyserSpigotLegacyNativeWorldManager(GeyserSpigotPlugin plugin, boolean isPaper) {
|
||||
super(plugin, isPaper);
|
||||
IntList allBlockStates = adapter.getAllBlockStates();
|
||||
oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size());
|
||||
ProtocolVersion serverVersion = plugin.getServerProtocolVersion();
|
||||
|
|
|
@ -26,20 +26,26 @@
|
|||
package org.geysermc.geyser.platform.spigot.world.manager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.adapters.WorldAdapter;
|
||||
import org.geysermc.geyser.adapters.paper.PaperAdapters;
|
||||
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
||||
import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
||||
protected final SpigotWorldAdapter adapter;
|
||||
protected final WorldAdapter<World> adapter;
|
||||
|
||||
public GeyserSpigotNativeWorldManager(Plugin plugin) {
|
||||
public GeyserSpigotNativeWorldManager(Plugin plugin, boolean isPaper) {
|
||||
super(plugin);
|
||||
adapter = SpigotAdapters.getWorldAdapter();
|
||||
if (isPaper) {
|
||||
adapter = PaperAdapters.getWorldAdapter();
|
||||
} else {
|
||||
adapter = SpigotAdapters.getWorldAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
package org.geysermc.geyser.platform.spigot.world.manager;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityInfo;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityInfo;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
@ -39,7 +39,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.erosion.bukkit.BukkitLecterns;
|
||||
import org.geysermc.erosion.bukkit.BukkitUtils;
|
||||
import org.geysermc.erosion.bukkit.PickBlockUtils;
|
||||
import org.geysermc.erosion.bukkit.SchedulerUtils;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.level.GameRule;
|
||||
|
@ -205,8 +204,8 @@ public class GeyserSpigotWorldManager extends WorldManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CompletableFuture<@Nullable CompoundTag> getPickItemNbt(GeyserSession session, int x, int y, int z, boolean addNbtData) {
|
||||
CompletableFuture<@Nullable CompoundTag> future = new CompletableFuture<>();
|
||||
public @NonNull CompletableFuture<@Nullable DataComponents> getPickItemComponents(GeyserSession session, int x, int y, int z, boolean addNbtData) {
|
||||
CompletableFuture<@Nullable DataComponents> future = new CompletableFuture<>();
|
||||
Player bukkitPlayer;
|
||||
if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUuid())) == null) {
|
||||
future.complete(null);
|
||||
|
@ -215,7 +214,7 @@ public class GeyserSpigotWorldManager extends WorldManager {
|
|||
Block block = bukkitPlayer.getWorld().getBlockAt(x, y, z);
|
||||
// Paper 1.19.3 complains about async access otherwise.
|
||||
// java.lang.IllegalStateException: Tile is null, asynchronous access?
|
||||
SchedulerUtils.runTask(this.plugin, () -> future.complete(PickBlockUtils.pickBlock(block)), block);
|
||||
SchedulerUtils.runTask(this.plugin, () -> future.complete(/*PickBlockUtils.pickBlock(block)*/ null), block); // TODO fix erosion once clear how to handle this
|
||||
return future;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
package org.geysermc.geyser.platform.velocity;
|
||||
|
||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||
import com.velocitypowered.api.network.ProtocolState;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.InboundConnection;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
|
@ -88,6 +89,11 @@ public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough {
|
|||
public ProtocolVersion getProtocolVersion() {
|
||||
return ProtocolVersion.MAXIMUM_VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolState getProtocolState() {
|
||||
return ProtocolState.STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ indra {
|
|||
tasks {
|
||||
processResources {
|
||||
// Spigot, BungeeCord, Velocity, Fabric, ViaProxy, NeoForge
|
||||
filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/mods.toml")) {
|
||||
filesMatching(listOf("plugin.yml", "bungee.yml", "velocity-plugin.json", "fabric.mod.json", "viaproxy.yml", "META-INF/neoforge.mods.toml")) {
|
||||
expand(
|
||||
"id" to "geyser",
|
||||
"name" to "Geyser",
|
||||
|
|
|
@ -39,13 +39,19 @@ provided("io.netty", "netty-resolver-dns-native-macos")
|
|||
provided("org.ow2.asm", "asm")
|
||||
|
||||
architectury {
|
||||
minecraft = "1.20.4"
|
||||
minecraft = "1.20.5"
|
||||
}
|
||||
|
||||
loom {
|
||||
silentMojangMappingsLicense()
|
||||
}
|
||||
|
||||
indra {
|
||||
javaVersions {
|
||||
target(21)
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
create("includeTransitive").isTransitive = true
|
||||
}
|
||||
|
@ -104,7 +110,7 @@ afterEvaluate {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
minecraft("com.mojang:minecraft:1.20.4")
|
||||
minecraft("com.mojang:minecraft:1.20.5")
|
||||
mappings(loom.officialMojangMappings())
|
||||
}
|
||||
|
||||
|
@ -128,6 +134,6 @@ modrinth {
|
|||
syncBodyFrom.set(rootProject.file("README.md").readText())
|
||||
|
||||
uploadFile.set(tasks.getByPath("remapModrinthJar"))
|
||||
gameVersions.addAll("1.20.4")
|
||||
gameVersions.addAll("1.20.5", "1.20.6")
|
||||
failSilently.set(true)
|
||||
}
|
|
@ -29,7 +29,6 @@ import com.fasterxml.jackson.core.JsonParser;
|
|||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.steveice10.packetlib.tcp.TcpSession;
|
||||
import io.netty.channel.epoll.Epoll;
|
||||
import io.netty.util.NettyRuntime;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
|
@ -46,7 +45,6 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
|||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.cumulus.form.Form;
|
||||
import org.geysermc.cumulus.form.util.FormBuilder;
|
||||
import org.geysermc.erosion.packet.Packets;
|
||||
import org.geysermc.floodgate.crypto.AesCipher;
|
||||
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
||||
import org.geysermc.floodgate.crypto.Base64Topping;
|
||||
|
@ -86,6 +84,7 @@ import org.geysermc.geyser.text.GeyserLocale;
|
|||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.*;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
@ -384,7 +383,7 @@ public class GeyserImpl implements GeyserApi {
|
|||
|
||||
this.newsHandler = new NewsHandler(BRANCH, this.buildNumber());
|
||||
|
||||
Packets.initGeyser();
|
||||
//Packets.initGeyser();
|
||||
|
||||
if (Epoll.isAvailable()) {
|
||||
this.erosionUnixListener = new UnixSocketClientListener();
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.command.defaults;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.ClientCommand;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.command.GeyserCommand;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
|
||||
|
||||
public class StatisticsCommand extends GeyserCommand {
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ package org.geysermc.geyser.dump;
|
|||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
@ -56,12 +56,7 @@ import java.net.InetSocketAddress;
|
|||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.factory.EntityFactory;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.translator.entity.EntityMetadataTranslator;
|
||||
|
@ -49,10 +50,10 @@ import java.util.function.BiConsumer;
|
|||
* @param <T> the entity type this definition represents
|
||||
*/
|
||||
public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, EntityType entityType, String identifier,
|
||||
float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
float width, float height, float offset, GeyserEntityProperties registeredProperties, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
|
||||
public static <T extends Entity> Builder<T> inherited(EntityFactory<T> factory, EntityDefinition<? super T> parent) {
|
||||
return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators));
|
||||
return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, parent.registeredProperties, new ObjectArrayList<>(parent.translators));
|
||||
}
|
||||
|
||||
public static <T extends Entity> Builder<T> builder(EntityFactory<T> factory) {
|
||||
|
@ -87,6 +88,7 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
private float width;
|
||||
private float height;
|
||||
private float offset = 0.00001f;
|
||||
private GeyserEntityProperties registeredProperties;
|
||||
private final List<EntityMetadataTranslator<? super T, ?, ?>> translators;
|
||||
|
||||
private Builder(EntityFactory<T> factory) {
|
||||
|
@ -94,13 +96,14 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
translators = new ObjectArrayList<>();
|
||||
}
|
||||
|
||||
public Builder(EntityFactory<T> factory, EntityType type, String identifier, float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
public Builder(EntityFactory<T> factory, EntityType type, String identifier, float width, float height, float offset, GeyserEntityProperties registeredProperties, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
this.factory = factory;
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.offset = offset;
|
||||
this.registeredProperties = registeredProperties;
|
||||
this.translators = translators;
|
||||
}
|
||||
|
||||
|
@ -127,6 +130,11 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> properties(GeyserEntityProperties registeredProperties) {
|
||||
this.registeredProperties = registeredProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <U, EM extends EntityMetadata<U, ? extends MetadataType<U>>> Builder<T> addTranslator(MetadataType<U> type, BiConsumer<T, EM> translateFunction) {
|
||||
translators.add(new EntityMetadataTranslator<>(type, translateFunction));
|
||||
return this;
|
||||
|
@ -149,10 +157,13 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
if (identifier == null && type != null) {
|
||||
identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, translators);
|
||||
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, registeredProperties, translators);
|
||||
if (register && definition.entityType() != null) {
|
||||
Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition);
|
||||
Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition);
|
||||
if (definition.registeredProperties() != null) {
|
||||
Registries.BEDROCK_ENTITY_PROPERTIES.get().add(definition.registeredProperties().toNbtMap(identifier));
|
||||
}
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
||||
import org.geysermc.geyser.entity.type.*;
|
||||
import org.geysermc.geyser.entity.type.living.*;
|
||||
import org.geysermc.geyser.entity.type.living.animal.*;
|
||||
|
@ -53,8 +54,9 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
|
|||
public final class EntityDefinitions {
|
||||
public static final EntityDefinition<AllayEntity> ALLAY;
|
||||
public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD;
|
||||
public static final EntityDefinition<ArmadilloEntity> ARMADILLO;
|
||||
public static final EntityDefinition<ArmorStandEntity> ARMOR_STAND;
|
||||
public static final EntityDefinition<TippedArrowEntity> ARROW;
|
||||
public static final EntityDefinition<ArrowEntity> ARROW;
|
||||
public static final EntityDefinition<AxolotlEntity> AXOLOTL;
|
||||
public static final EntityDefinition<BatEntity> BAT;
|
||||
public static final EntityDefinition<BeeEntity> BEE;
|
||||
|
@ -200,7 +202,6 @@ public final class EntityDefinitions {
|
|||
.type(EntityType.AREA_EFFECT_CLOUD)
|
||||
.height(0.5f).width(1.0f)
|
||||
.addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue()))
|
||||
.addTranslator(null) // Waiting
|
||||
.addTranslator(MetadataType.PARTICLE, AreaEffectCloudEntity::setParticle)
|
||||
.build();
|
||||
|
@ -376,10 +377,10 @@ public final class EntityDefinitions {
|
|||
.addTranslator(MetadataType.BYTE, AbstractArrowEntity::setArrowFlags)
|
||||
.addTranslator(null) // "Piercing level"
|
||||
.build();
|
||||
ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase)
|
||||
ARROW = EntityDefinition.inherited(ArrowEntity::new, abstractArrowBase)
|
||||
.type(EntityType.ARROW)
|
||||
.heightAndWidth(0.25f)
|
||||
.addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor)
|
||||
.addTranslator(MetadataType.INT, ArrowEntity::setPotionEffectColor)
|
||||
.build();
|
||||
SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase)
|
||||
.type(EntityType.SPECTRAL_ARROW)
|
||||
|
@ -452,8 +453,7 @@ public final class EntityDefinitions {
|
|||
EntityDefinition<LivingEntity> livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase)
|
||||
.addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags)
|
||||
.addTranslator(MetadataType.FLOAT, LivingEntity::setHealth)
|
||||
.addTranslator(MetadataType.INT,
|
||||
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue()))
|
||||
.addTranslator(MetadataType.PARTICLES, LivingEntity::setParticles)
|
||||
.addTranslator(MetadataType.BOOLEAN,
|
||||
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_AMBIENCE, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0)))
|
||||
.addTranslator(null) // Arrow count
|
||||
|
@ -672,7 +672,7 @@ public final class EntityDefinitions {
|
|||
SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase)
|
||||
.type(EntityType.SLIME)
|
||||
.heightAndWidth(0.51f)
|
||||
.addTranslator(MetadataType.INT, SlimeEntity::setScale)
|
||||
.addTranslator(MetadataType.INT, SlimeEntity::setSlimeScale)
|
||||
.build();
|
||||
MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME)
|
||||
.type(EntityType.MAGMA_CUBE)
|
||||
|
@ -770,6 +770,20 @@ public final class EntityDefinitions {
|
|||
|
||||
// Extends ageable
|
||||
{
|
||||
ARMADILLO = EntityDefinition.inherited(ArmadilloEntity::new, ageableEntityBase)
|
||||
.type(EntityType.ARMADILLO)
|
||||
.height(0.65f).width(0.7f)
|
||||
.properties(new GeyserEntityProperties.Builder()
|
||||
.addEnum(
|
||||
"minecraft:armadillo_state",
|
||||
"unrolled",
|
||||
"rolled_up",
|
||||
"rolled_up_peeking",
|
||||
"rolled_up_relaxing",
|
||||
"rolled_up_unrolling")
|
||||
.build())
|
||||
.addTranslator(MetadataType.ARMADILLO_STATE, ArmadilloEntity::setArmadilloState)
|
||||
.build();
|
||||
AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase)
|
||||
.type(EntityType.AXOLOTL)
|
||||
.height(0.42f).width(0.7f)
|
||||
|
@ -780,6 +794,9 @@ public final class EntityDefinitions {
|
|||
BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase)
|
||||
.type(EntityType.BEE)
|
||||
.heightAndWidth(0.6f)
|
||||
.properties(new GeyserEntityProperties.Builder()
|
||||
.addBoolean("minecraft:has_nectar")
|
||||
.build())
|
||||
.addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags)
|
||||
.addTranslator(MetadataType.INT, BeeEntity::setAngerTime)
|
||||
.build();
|
||||
|
@ -937,8 +954,7 @@ public final class EntityDefinitions {
|
|||
LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase)
|
||||
.type(EntityType.LLAMA)
|
||||
.height(1.87f).width(0.9f)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.STRENGTH, entityMetadata.getValue()))
|
||||
.addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor)
|
||||
.addTranslator(MetadataType.INT, LlamaEntity::setStrength)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, entityMetadata.getValue()))
|
||||
.build();
|
||||
TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA)
|
||||
|
@ -947,7 +963,7 @@ public final class EntityDefinitions {
|
|||
.build();
|
||||
}
|
||||
|
||||
EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.inherited(TameableEntity::new, ageableEntityBase)
|
||||
EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.<TameableEntity>inherited(null, ageableEntityBase) // No factory, is abstract
|
||||
.addTranslator(MetadataType.BYTE, TameableEntity::setTameableFlags)
|
||||
.addTranslator(MetadataType.OPTIONAL_UUID, TameableEntity::setOwner)
|
||||
.build();
|
||||
|
@ -971,6 +987,7 @@ public final class EntityDefinitions {
|
|||
.addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||
.addTranslator(MetadataType.INT, WolfEntity::setCollarColor)
|
||||
.addTranslator(MetadataType.INT, WolfEntity::setWolfAngerTime)
|
||||
.addTranslator(MetadataType.WOLF_VARIANT, WolfEntity::setWolfVariant)
|
||||
.build();
|
||||
|
||||
// As of 1.18 these don't track entity data at all
|
||||
|
|
|
@ -49,6 +49,7 @@ public enum GeyserAttributeType {
|
|||
ATTACK_KNOCKBACK("minecraft:generic.attack_knockback", null, 1.5f, Float.MAX_VALUE, 0f),
|
||||
ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f),
|
||||
MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f),
|
||||
SCALE("minecraft:generic.scale", null, 0.0625f, 16f, 1f), // Unused. Do we need this?
|
||||
|
||||
// Bedrock Attributes
|
||||
ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f),
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.entity.properties;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.entity.properties.type.BooleanProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.EnumProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.FloatProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.IntProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.PropertyType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode
|
||||
@ToString
|
||||
public class GeyserEntityProperties {
|
||||
private final ObjectArrayList<PropertyType> properties;
|
||||
private final Object2IntMap<String> propertyIndices;
|
||||
|
||||
private GeyserEntityProperties(ObjectArrayList<PropertyType> properties,
|
||||
Object2IntMap<String> propertyIndices) {
|
||||
this.properties = properties;
|
||||
this.propertyIndices = propertyIndices;
|
||||
}
|
||||
|
||||
public NbtMap toNbtMap(String entityType) {
|
||||
NbtMapBuilder mapBuilder = NbtMap.builder();
|
||||
List<NbtMap> nbtProperties = new ArrayList<>();
|
||||
|
||||
for (PropertyType property : properties) {
|
||||
nbtProperties.add(property.nbtMap());
|
||||
}
|
||||
mapBuilder.putList("properties", NbtType.COMPOUND, nbtProperties);
|
||||
|
||||
return mapBuilder.putString("type", entityType).build();
|
||||
}
|
||||
|
||||
public @NonNull List<PropertyType> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public int getPropertyIndex(String name) {
|
||||
return propertyIndices.getOrDefault(name, -1);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final ObjectArrayList<PropertyType> properties = new ObjectArrayList<>();
|
||||
private final Object2IntMap<String> propertyIndices = new Object2IntOpenHashMap<>();
|
||||
|
||||
public Builder addInt(@NonNull String name, int min, int max) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new IntProperty(name, min, max);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addInt(@NonNull String name) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new IntProperty(name, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addFloat(@NonNull String name, float min, float max) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new FloatProperty(name, min, max);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addFloat(@NonNull String name) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new FloatProperty(name, Float.MIN_NORMAL, Float.MAX_VALUE);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addBoolean(@NonNull String name) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new BooleanProperty(name);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addEnum(@NonNull String name, List<String> values) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new EnumProperty(name, values);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addEnum(@NonNull String name, String... values) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
List<String> valuesList = Arrays.asList(values); // Convert array to list
|
||||
PropertyType property = new EnumProperty(name, valuesList);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeyserEntityProperties build() {
|
||||
return new GeyserEntityProperties(properties, propertyIndices);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2023 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.entity.properties;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.FloatEntityProperty;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.IntEntityProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.EnumProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.PropertyType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GeyserEntityPropertyManager {
|
||||
|
||||
private final GeyserEntityProperties properties;
|
||||
|
||||
private final ObjectArrayList<IntEntityProperty> intEntityProperties = new ObjectArrayList<>();
|
||||
private final ObjectArrayList<FloatEntityProperty> floatEntityProperties = new ObjectArrayList<>();
|
||||
|
||||
public GeyserEntityPropertyManager(GeyserEntityProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void add(String propertyName, int value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
intEntityProperties.add(new IntEntityProperty(index, value));
|
||||
}
|
||||
|
||||
public void add(String propertyName, boolean value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
intEntityProperties.add(new IntEntityProperty(index, value ? 1 : 0));
|
||||
}
|
||||
|
||||
public void add(String propertyName, String value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
PropertyType property = properties.getProperties().get(index);
|
||||
int enumIndex = ((EnumProperty) property).getIndex(value);
|
||||
intEntityProperties.add(new IntEntityProperty(index, enumIndex));
|
||||
}
|
||||
|
||||
public void add(String propertyName, float value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
floatEntityProperties.add(new FloatEntityProperty(index, value));
|
||||
}
|
||||
|
||||
public boolean hasFloatProperties() {
|
||||
return !this.floatEntityProperties.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasIntProperties() {
|
||||
return !this.intEntityProperties.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasProperties() {
|
||||
return hasFloatProperties() || hasIntProperties();
|
||||
}
|
||||
|
||||
public ObjectArrayList<IntEntityProperty> intProperties() {
|
||||
return this.intEntityProperties;
|
||||
}
|
||||
|
||||
public void applyIntProperties(List<IntEntityProperty> properties) {
|
||||
properties.addAll(intEntityProperties);
|
||||
intEntityProperties.clear();
|
||||
}
|
||||
|
||||
public ObjectArrayList<FloatEntityProperty> floatProperties() {
|
||||
return this.floatEntityProperties;
|
||||
}
|
||||
|
||||
public void applyFloatProperties(List<FloatEntityProperty> properties) {
|
||||
properties.addAll(floatEntityProperties);
|
||||
floatEntityProperties.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.entity.properties.type;
|
||||
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public class BooleanProperty implements PropertyType {
|
||||
private final String name;
|
||||
|
||||
public BooleanProperty(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putInt("type", 2)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.entity.properties.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EnumProperty implements PropertyType {
|
||||
private final String name;
|
||||
private final List<String> values;
|
||||
private final Object2IntMap<String> valueIndexMap;
|
||||
|
||||
public EnumProperty(String name, List<String> values) {
|
||||
this.name = name;
|
||||
this.values = values;
|
||||
this.valueIndexMap = new Object2IntOpenHashMap<>(values.size());
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
valueIndexMap.put(values.get(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putList("enum", NbtType.STRING, values)
|
||||
.putInt("type", 3)
|
||||
.build();
|
||||
}
|
||||
|
||||
public int getIndex(String value) {
|
||||
return valueIndexMap.getOrDefault(value, -1);
|
||||
}
|
||||
}
|
|
@ -23,34 +23,28 @@
|
|||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.item;
|
||||
package org.geysermc.geyser.entity.properties.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public interface DyeableLeatherItem {
|
||||
public class FloatProperty implements PropertyType {
|
||||
private final String name;
|
||||
private final float max;
|
||||
private final float min;
|
||||
|
||||
static void translateNbtToBedrock(CompoundTag tag) {
|
||||
CompoundTag displayTag = tag.get("display");
|
||||
if (displayTag == null) {
|
||||
return;
|
||||
}
|
||||
IntTag color = displayTag.remove("color");
|
||||
if (color != null) {
|
||||
tag.put(new IntTag("customColor", color.getValue()));
|
||||
}
|
||||
public FloatProperty(String name, float min, float max) {
|
||||
this.name = name;
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
static void translateNbtToJava(CompoundTag tag) {
|
||||
IntTag color = tag.get("customColor");
|
||||
if (color == null) {
|
||||
return;
|
||||
}
|
||||
CompoundTag displayTag = tag.get("display");
|
||||
if (displayTag == null) {
|
||||
displayTag = new CompoundTag("display");
|
||||
}
|
||||
displayTag.put(color);
|
||||
tag.remove("customColor");
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putFloat("max", max)
|
||||
.putFloat("min", min)
|
||||
.putInt("type", 1)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.entity.properties.type;
|
||||
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public class IntProperty implements PropertyType {
|
||||
private final String name;
|
||||
private final int max;
|
||||
private final int min;
|
||||
|
||||
public IntProperty(String name, int min, int max) {
|
||||
this.name = name;
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putInt("max", max)
|
||||
.putInt("min", min)
|
||||
.putInt("type", 0)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.entity.properties.type;
|
||||
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public interface PropertyType {
|
||||
NbtMap nbtMap();
|
||||
}
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.particle.Particle;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -35,6 +32,11 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -51,7 +53,7 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_DURATION, Integer.MAX_VALUE);
|
||||
|
||||
// This disabled client side shrink of the cloud
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.0f);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 3.0f);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_RATE, Float.MIN_VALUE);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, Float.MIN_VALUE);
|
||||
|
||||
|
@ -60,7 +62,7 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
|
||||
public void setRadius(FloatEntityMetadata entityMetadata) {
|
||||
// Anything less than 0.5 will cause the cloud to despawn
|
||||
float value = Math.max(entityMetadata.getPrimitiveValue(), 0.5f);
|
||||
float value = MathUtils.clamp(entityMetadata.getPrimitiveValue(), 0.5f, 32.0f);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, value);
|
||||
dirtyMetadata.put(EntityDataTypes.WIDTH, 2.0f * value);
|
||||
}
|
||||
|
@ -69,5 +71,9 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
Particle particle = entityMetadata.getValue();
|
||||
Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type ->
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type));
|
||||
|
||||
if (particle.getData() instanceof EntityEffectParticleData effectParticleData) {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, effectParticleData.getColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,21 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.item.TippedArrowPotion;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Internally this is known as TippedArrowEntity but is used with tipped arrows and normal arrows
|
||||
*/
|
||||
public class TippedArrowEntity extends AbstractArrowEntity {
|
||||
public class ArrowEntity extends AbstractArrowEntity {
|
||||
|
||||
public TippedArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
public ArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
|
@ -25,22 +25,21 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BoatEntity extends Entity implements Tickable {
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
|
|
@ -25,13 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -42,27 +35,26 @@ import org.cloudburstmc.math.vector.Vector3f;
|
|||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -126,6 +118,8 @@ public class Entity implements GeyserEntity {
|
|||
@Setter(AccessLevel.PROTECTED) // For players
|
||||
private boolean flagsDirty = false;
|
||||
|
||||
protected final GeyserEntityPropertyManager propertyManager;
|
||||
|
||||
public Entity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
this.session = session;
|
||||
|
||||
|
@ -140,6 +134,8 @@ public class Entity implements GeyserEntity {
|
|||
|
||||
this.valid = false;
|
||||
|
||||
this.propertyManager = new GeyserEntityPropertyManager(definition.registeredProperties());
|
||||
|
||||
setPosition(position);
|
||||
setAirSupply(getMaxAir());
|
||||
|
||||
|
@ -357,6 +353,23 @@ public class Entity implements GeyserEntity {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the Bedrock entity properties to the client
|
||||
*/
|
||||
public void updateBedrockEntityProperties() {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyManager.hasProperties()) {
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(geyserId);
|
||||
propertyManager.applyIntProperties(entityDataPacket.getProperties().getIntProperties());
|
||||
propertyManager.applyFloatProperties(entityDataPacket.getProperties().getFloatProperties());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFlags(ByteEntityMetadata entityMetadata) {
|
||||
byte xd = entityMetadata.getPrimitiveValue();
|
||||
setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,26 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||
import org.geysermc.floodgate.util.DeviceOs;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.level.FireworkColor;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -59,80 +51,16 @@ public class FireworkEntity extends Entity {
|
|||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
CompoundTag tag = item.getNbt();
|
||||
|
||||
if (tag == null) {
|
||||
DataComponents components = item.getDataComponents();
|
||||
if (components == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Remove once Mojang fixes bugs with fireworks crashing clients on these specific devices.
|
||||
// https://bugs.mojang.com/browse/MCPE-89115
|
||||
if (session.getClientData().getDeviceOs() == DeviceOs.XBOX
|
||||
|| session.getClientData().getDeviceOs() == DeviceOs.PS4) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag fireworks = tag.get("Fireworks");
|
||||
if (fireworks == null) {
|
||||
// Thank you Mineplex very cool
|
||||
return;
|
||||
}
|
||||
|
||||
NbtMapBuilder fireworksBuilder = NbtMap.builder();
|
||||
if (fireworks.get("Flight") != null) {
|
||||
fireworksBuilder.putByte("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue()));
|
||||
}
|
||||
|
||||
List<NbtMap> explosions = new ArrayList<>();
|
||||
if (fireworks.get("Explosions") != null) {
|
||||
for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) {
|
||||
CompoundTag effectData = (CompoundTag) effect;
|
||||
NbtMapBuilder effectBuilder = NbtMap.builder();
|
||||
|
||||
if (effectData.get("Type") != null) {
|
||||
effectBuilder.putByte("FireworkType", MathUtils.getNbtByte(effectData.get("Type").getValue()));
|
||||
}
|
||||
|
||||
if (effectData.get("Colors") != null) {
|
||||
int[] oldColors = (int[]) effectData.get("Colors").getValue();
|
||||
byte[] colors = new byte[oldColors.length];
|
||||
|
||||
int i = 0;
|
||||
for (int color : oldColors) {
|
||||
colors[i++] = FireworkColor.fromJavaRGB(color);
|
||||
}
|
||||
|
||||
effectBuilder.putByteArray("FireworkColor", colors);
|
||||
}
|
||||
|
||||
if (effectData.get("FadeColors") != null) {
|
||||
int[] oldColors = (int[]) effectData.get("FadeColors").getValue();
|
||||
byte[] colors = new byte[oldColors.length];
|
||||
|
||||
int i = 0;
|
||||
for (int color : oldColors) {
|
||||
colors[i++] = FireworkColor.fromJavaRGB(color);
|
||||
}
|
||||
|
||||
effectBuilder.putByteArray("FireworkFade", colors);
|
||||
}
|
||||
|
||||
if (effectData.get("Trail") != null) {
|
||||
effectBuilder.putByte("FireworkTrail", MathUtils.getNbtByte(effectData.get("Trail").getValue()));
|
||||
}
|
||||
|
||||
if (effectData.get("Flicker") != null) {
|
||||
effectBuilder.putByte("FireworkFlicker", MathUtils.getNbtByte(effectData.get("Flicker").getValue()));
|
||||
}
|
||||
|
||||
explosions.add(effectBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
fireworksBuilder.putList("Explosions", NbtType.COMPOUND, explosions);
|
||||
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.put("Fireworks", fireworksBuilder.build());
|
||||
// TODO this looked the same, so I'm going to assume it is and (keep below comment if true)
|
||||
// Translate using item methods to get firework NBT for Bedrock
|
||||
BedrockItemBuilder builder = new BedrockItemBuilder();
|
||||
Items.FIREWORK_ROCKET.translateComponentsToBedrock(session, components, builder);
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_FIREWORK, builder.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.erosion.util.BlockPositionIterator;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
|
@ -38,6 +37,7 @@ import org.geysermc.geyser.level.physics.BoundingBox;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,16 +25,16 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
|
@ -37,7 +35,9 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
|
@ -25,12 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -39,12 +34,17 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,16 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -55,8 +45,23 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -69,7 +74,7 @@ public class LivingEntity extends Entity {
|
|||
protected ItemData leggings = ItemData.AIR;
|
||||
protected ItemData boots = ItemData.AIR;
|
||||
protected ItemData hand = ItemData.AIR;
|
||||
protected ItemData offHand = ItemData.AIR;
|
||||
protected ItemData offhand = ItemData.AIR;
|
||||
|
||||
@Getter(value = AccessLevel.NONE)
|
||||
protected float health = 1f; // The default value in Java Edition before any entity metadata is sent
|
||||
|
@ -81,12 +86,58 @@ public class LivingEntity extends Entity {
|
|||
*/
|
||||
private boolean isMaxFrozenState = false;
|
||||
|
||||
/**
|
||||
* The base scale entity data, without attributes applied. Used for such cases as baby variants.
|
||||
*/
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private float scale;
|
||||
/**
|
||||
* The scale sent through the Java attributes packet
|
||||
*/
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private float attributeScale;
|
||||
|
||||
public LivingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setHelmet(ItemStack stack) {
|
||||
this.helmet = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setChestplate(ItemStack stack) {
|
||||
this.chestplate = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setLeggings(ItemStack stack) {
|
||||
this.leggings = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setBoots(ItemStack stack) {
|
||||
this.boots = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setHand(ItemStack stack) {
|
||||
this.hand = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setOffhand(ItemStack stack) {
|
||||
this.offhand = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void switchHands() {
|
||||
ItemData offhand = this.offhand;
|
||||
this.offhand = this.hand;
|
||||
this.hand = offhand;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeMetadata() {
|
||||
// Initialize here so overriding classes don't have 0 values
|
||||
this.scale = 1f;
|
||||
this.attributeScale = 1f;
|
||||
super.initializeMetadata();
|
||||
// Matches Bedrock behavior; is always set to this
|
||||
dirtyMetadata.put(EntityDataTypes.STRUCTURAL_INTEGRITY, 1);
|
||||
|
@ -121,6 +172,37 @@ public class LivingEntity extends Entity {
|
|||
session.sendUpstreamPacket(attributesPacket);
|
||||
}
|
||||
|
||||
// TODO: support all particle types
|
||||
public void setParticles(ObjectEntityMetadata<List<Particle>> entityMetadata) {
|
||||
List<Particle> particles = entityMetadata.getValue();
|
||||
float r = 0f;
|
||||
float g = 0f;
|
||||
float b = 0f;
|
||||
|
||||
int count = 0;
|
||||
for (Particle particle : particles) {
|
||||
if (particle.getType() != ParticleType.ENTITY_EFFECT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int color = ((EntityEffectParticleData) particle.getData()).getColor();
|
||||
r += ((color >> 16) & 0xFF) / 255f;
|
||||
g += ((color >> 8) & 0xFF) / 255f;
|
||||
b += ((color) & 0xFF) / 255f;
|
||||
count++;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (count > 0) {
|
||||
r = r / count * 255f;
|
||||
g = g / count * 255f;
|
||||
b = b / count * 255f;
|
||||
result = (int) r << 16 | (int) g << 8 | (int) b;
|
||||
}
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, result);
|
||||
}
|
||||
|
||||
public @Nullable Vector3i setBedPosition(EntityMetadata<Optional<Vector3i>, ?> entityMetadata) {
|
||||
Optional<Vector3i> optionalPos = entityMetadata.getValue();
|
||||
if (optionalPos.isPresent()) {
|
||||
|
@ -135,7 +217,7 @@ public class LivingEntity extends Entity {
|
|||
protected boolean hasShield(boolean offhand) {
|
||||
ItemMapping shieldMapping = session.getItemMappings().getStoredItems().shield();
|
||||
if (offhand) {
|
||||
return offHand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
return this.offhand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
} else {
|
||||
return hand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
}
|
||||
|
@ -164,6 +246,21 @@ public class LivingEntity extends Entity {
|
|||
return freezingPercentage;
|
||||
}
|
||||
|
||||
protected void setScale(float scale) {
|
||||
this.scale = scale;
|
||||
applyScale();
|
||||
}
|
||||
|
||||
private void setAttributeScale(float scale) {
|
||||
this.attributeScale = scale;
|
||||
applyScale();
|
||||
}
|
||||
|
||||
private void applyScale() {
|
||||
// Take any adjustments Bedrock requires, and compute it alongside the attribute's additional changes
|
||||
this.dirtyMetadata.put(EntityDataTypes.SCALE, scale * attributeScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Bedrock health attribute constructed from the data sent from the server
|
||||
*/
|
||||
|
@ -194,9 +291,9 @@ public class LivingEntity extends Entity {
|
|||
/**
|
||||
* Checks to see if a nametag interaction would go through.
|
||||
*/
|
||||
// Implementation note for 1.20.5: this code was moved to the NameTag item.
|
||||
protected final InteractionResult checkInteractWithNameTag(GeyserItemStack itemStack) {
|
||||
CompoundTag nbt = itemStack.getNbt();
|
||||
if (nbt != null && nbt.get("display") instanceof CompoundTag displayTag && displayTag.get("Name") instanceof StringTag) {
|
||||
if (itemStack.getComponent(DataComponentType.CUSTOM_NAME) != null) {
|
||||
// The mob shall be named
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
@ -247,7 +344,7 @@ public class LivingEntity extends Entity {
|
|||
|
||||
MobEquipmentPacket offHandPacket = new MobEquipmentPacket();
|
||||
offHandPacket.setRuntimeEntityId(geyserId);
|
||||
offHandPacket.setItem(offHand);
|
||||
offHandPacket.setItem(offhand);
|
||||
offHandPacket.setHotbarSlot(-1);
|
||||
offHandPacket.setInventorySlot(0);
|
||||
offHandPacket.setContainerId(ContainerId.OFFHAND);
|
||||
|
@ -299,7 +396,12 @@ public class LivingEntity extends Entity {
|
|||
case GENERIC_MOVEMENT_SPEED -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.MOVEMENT_SPEED));
|
||||
case GENERIC_FOLLOW_RANGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.FOLLOW_RANGE));
|
||||
case GENERIC_KNOCKBACK_RESISTANCE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.KNOCKBACK_RESISTANCE));
|
||||
case HORSE_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH));
|
||||
case GENERIC_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH));
|
||||
case GENERIC_SCALE -> {
|
||||
// Attribute on Java, entity data on Bedrock
|
||||
setAttributeScale((float) AttributeUtils.calculateValue(javaAttribute));
|
||||
updateBedrockMetadata();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
@ -35,6 +32,9 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.PaintingType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class PaintingEntity extends Entity {
|
|||
// Wait until we get the metadata needed
|
||||
}
|
||||
|
||||
public void setPaintingType(ObjectEntityMetadata<com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType> entityMetadata) {
|
||||
public void setPaintingType(ObjectEntityMetadata<org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType> entityMetadata) {
|
||||
PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue());
|
||||
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
||||
addPaintingPacket.setUniqueEntityId(geyserId);
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -34,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -38,6 +34,11 @@ import org.geysermc.geyser.inventory.item.Potion;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
@ -53,21 +54,22 @@ public class ThrownPotionEntity extends ThrowableItemEntity {
|
|||
public void setItem(EntityMetadata<ItemStack, ?> entityMetadata) {
|
||||
ItemStack itemStack = entityMetadata.getValue();
|
||||
if (itemStack == null) {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
||||
dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0);
|
||||
setFlag(EntityFlag.ENCHANTED, false);
|
||||
setFlag(EntityFlag.LINGERING, false);
|
||||
} else {
|
||||
// As of Java 1.19.3, the server/client doesn't seem to care of the item is actually a potion?
|
||||
if (itemStack.getNbt() != null) {
|
||||
Tag potionTag = itemStack.getNbt().get("Potion");
|
||||
if (potionTag instanceof StringTag) {
|
||||
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
||||
DataComponents components = itemStack.getDataComponents();
|
||||
if (components != null) {
|
||||
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
|
||||
if (potionContents != null) {
|
||||
Potion potion = Potion.getByJavaId(potionContents.getPotionId());
|
||||
if (potion != null) {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId());
|
||||
dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, potion.getBedrockId());
|
||||
setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
|
||||
} else {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue());
|
||||
dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0);
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionContents.getPotionId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -34,6 +33,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,12 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -44,12 +43,12 @@ public class AgeableEntity extends CreatureEntity {
|
|||
protected void initializeMetadata() {
|
||||
super.initializeMetadata();
|
||||
// Required as of 1.19.3 Java
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, getAdultSize());
|
||||
setScale(getAdultSize());
|
||||
}
|
||||
|
||||
public void setBaby(BooleanEntityMetadata entityMetadata) {
|
||||
boolean isBaby = entityMetadata.getPrimitiveValue();
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? getBabySize() : getAdultSize());
|
||||
setScale(isBaby ? getBabySize() : getAdultSize());
|
||||
setFlag(EntityFlag.BABY, isBaby);
|
||||
|
||||
setBoundingBoxHeight(definition.height() * (isBaby ? getBabySize() : getAdultSize()));
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -43,6 +39,11 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
@ -257,38 +258,38 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setHelmet(ItemData helmet) {
|
||||
public void setHelmet(ItemStack helmet) {
|
||||
super.setHelmet(helmet);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChestplate(ItemData chestplate) {
|
||||
public void setChestplate(ItemStack chestplate) {
|
||||
super.setChestplate(chestplate);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeggings(ItemData leggings) {
|
||||
public void setLeggings(ItemStack leggings) {
|
||||
super.setLeggings(leggings);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoots(ItemData boots) {
|
||||
public void setBoots(ItemStack boots) {
|
||||
super.setBoots(boots);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHand(ItemData hand) {
|
||||
public void setHand(ItemStack hand) {
|
||||
super.setHand(hand);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOffHand(ItemData offHand) {
|
||||
super.setOffHand(offHand);
|
||||
public void setOffhand(ItemStack offHand) {
|
||||
super.setOffhand(offHand);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
|
@ -310,7 +311,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
if (!isInvisible) {
|
||||
// The armor stand isn't invisible. We good.
|
||||
setFlag(EntityFlag.INVISIBLE, false);
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, getScale());
|
||||
setScale(getScale());
|
||||
updateOffsetRequirement(false);
|
||||
|
||||
if (secondEntity != null) {
|
||||
|
@ -324,9 +325,9 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
}
|
||||
boolean isNametagEmpty = nametag.isEmpty();
|
||||
if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR)
|
||||
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) {
|
||||
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) {
|
||||
// Reset scale of the proper armor stand
|
||||
this.dirtyMetadata.put(EntityDataTypes.SCALE, getScale());
|
||||
setScale(getScale());
|
||||
// Set the proper armor stand to invisible to show armor
|
||||
setFlag(EntityFlag.INVISIBLE, true);
|
||||
// Update the position of the armor stand
|
||||
|
@ -349,7 +350,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
// Guarantee this copy is NOT invisible
|
||||
secondEntity.setFlag(EntityFlag.INVISIBLE, false);
|
||||
// Scale to 0 to show nametag
|
||||
secondEntity.getDirtyMetadata().put(EntityDataTypes.SCALE, 0.0f);
|
||||
secondEntity.setScale(0f);
|
||||
// No bounding box as we don't want to interact with this entity
|
||||
secondEntity.getDirtyMetadata().put(EntityDataTypes.WIDTH, 0.0f);
|
||||
secondEntity.getDirtyMetadata().put(EntityDataTypes.HEIGHT, 0.0f);
|
||||
|
@ -359,7 +360,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
} else if (isNametagEmpty) {
|
||||
// We can just make an invisible entity
|
||||
// Reset scale of the proper armor stand
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, getScale());
|
||||
setScale(getScale());
|
||||
// Set the proper armor stand to invisible to show armor
|
||||
setFlag(EntityFlag.INVISIBLE, true);
|
||||
// Update offset
|
||||
|
@ -373,7 +374,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
// Nametag is not empty and there is no armor
|
||||
// We don't need to make a new entity
|
||||
setFlag(EntityFlag.INVISIBLE, false);
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, 0.0f);
|
||||
setScale(0f);
|
||||
// As the above is applied, we need an offset
|
||||
updateOffsetRequirement(!isMarker);
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -49,7 +50,7 @@ public class DolphinEntity extends WaterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||
return InteractiveTag.FEED;
|
||||
}
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
|
@ -58,7 +59,7 @@ public class DolphinEntity extends WaterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||
// Feed
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -35,6 +34,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -40,6 +38,8 @@ import org.geysermc.geyser.item.type.SpawnEggItem;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -39,8 +38,8 @@ public class SlimeEntity extends MobEntity {
|
|||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setScale(IntEntityMetadata entityMetadata) {
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, 0.10f + entityMetadata.getPrimitiveValue());
|
||||
public void setSlimeScale(IntEntityMetadata entityMetadata) {
|
||||
setScale(0.10f + entityMetadata.getPrimitiveValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -62,6 +62,6 @@ public class TadpoleEntity extends AbstractFishEntity {
|
|||
}
|
||||
|
||||
private boolean isFood(GeyserItemStack itemStack) {
|
||||
return itemStack.asItem() == Items.SLIME_BALL;
|
||||
return session.getTagCache().is(ItemTag.FROG_FOOD, itemStack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,39 +25,40 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.AgeableEntity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AnimalEntity extends AgeableEntity {
|
||||
public abstract class AnimalEntity extends AgeableEntity {
|
||||
|
||||
public AnimalEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public final boolean canEat(GeyserItemStack itemStack) {
|
||||
return canEat(itemStack.asItem());
|
||||
protected final boolean canEat(GeyserItemStack itemStack) {
|
||||
ItemTag tag = getFoodTag();
|
||||
if (tag == null) {
|
||||
return false;
|
||||
}
|
||||
return session.getTagCache().is(tag, itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this is a valid item to breed with for this animal.
|
||||
* @return the tag associated with this animal for eating food. Null for nothing or different behavior.
|
||||
*/
|
||||
public boolean canEat(Item item) {
|
||||
// This is what it defaults to. OK.
|
||||
return item == Items.WHEAT;
|
||||
}
|
||||
protected abstract @Nullable ItemTag getFoodTag();
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 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.entity.type.living.animal;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ArmadilloEntity extends AnimalEntity {
|
||||
private ArmadilloState armadilloState = ArmadilloState.IDLE;
|
||||
|
||||
public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid,
|
||||
EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setArmadilloState(ObjectEntityMetadata<ArmadilloState> entityMetadata) {
|
||||
armadilloState = entityMetadata.getValue();
|
||||
|
||||
switch (armadilloState) {
|
||||
case IDLE -> propertyManager.add("minecraft:armadillo_state", "unrolled");
|
||||
case ROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up");
|
||||
case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing");
|
||||
case UNROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up_unrolling");
|
||||
}
|
||||
|
||||
updateBedrockEntityProperties();
|
||||
}
|
||||
|
||||
public void onPeeking() {
|
||||
// Technically we should wait if not currently scared
|
||||
if (armadilloState == ArmadilloState.SCARED) {
|
||||
propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking");
|
||||
updateBedrockEntityProperties();
|
||||
|
||||
// Needed for consecutive peeks
|
||||
session.scheduleInEventLoop(() -> {
|
||||
if (armadilloState == ArmadilloState.SCARED) {
|
||||
propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing");
|
||||
updateBedrockEntityProperties();
|
||||
}
|
||||
}, 250, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.ARMADILLO_FOOD;
|
||||
}
|
||||
}
|
|
@ -25,19 +25,20 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -60,8 +61,9 @@ public class AxolotlEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isAxolotlTemptItem(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.AXOLOTL_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,16 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -57,7 +58,8 @@ public class BeeEntity extends AnimalEntity {
|
|||
// If the bee has stung
|
||||
dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, (xd & 0x04) == 0x04 ? 1 : 0);
|
||||
// If the bee has nectar or not
|
||||
setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08);
|
||||
propertyManager.add("minecraft:has_nectar", (xd & 0x08) == 0x08);
|
||||
updateBedrockEntityProperties();
|
||||
}
|
||||
|
||||
public void setAngerTime(IntEntityMetadata entityMetadata) {
|
||||
|
@ -66,7 +68,8 @@ public class BeeEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isFlower(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.BEE_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,24 +25,23 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChickenEntity extends AnimalEntity {
|
||||
private static final Set<Item> VALID_FOOD = Set.of(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS);
|
||||
|
||||
public ChickenEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return VALID_FOOD.contains(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.CHICKEN_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -34,8 +34,10 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -64,4 +66,10 @@ public class CowEntity extends AnimalEntity {
|
|||
session.playSoundEvent(SoundEvent.MILK, position);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.COW_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -55,7 +56,8 @@ public class FoxEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isFoxFood(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.FOX_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
|
@ -76,7 +76,8 @@ public class FrogEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.SLIME_BALL;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.FROG_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -37,7 +35,11 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -94,4 +96,10 @@ public class GoatEntity extends AnimalEntity {
|
|||
private void setHornCount() {
|
||||
dirtyMetadata.put(EntityDataTypes.GOAT_HORN_COUNT, (hasLeftHorn ? 1 : 0) + (hasRightHorn ? 1 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.GOAT_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -54,8 +54,9 @@ public class HoglinEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.CRIMSON_FUNGUS;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.HOGLIN_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,22 +25,22 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.FlowerItem;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class MooshroomEntity extends AnimalEntity {
|
||||
public class MooshroomEntity extends CowEntity {
|
||||
private boolean isBrown = false;
|
||||
|
||||
public MooshroomEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
|
@ -77,7 +77,7 @@ public class MooshroomEntity extends AnimalEntity {
|
|||
} else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) {
|
||||
// Shear items
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.asItem() instanceof FlowerItem) {
|
||||
} else if (isBrown && session.getTagCache().is(ItemTag.SMALL_FLOWERS, itemInHand)) {
|
||||
// ?
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -46,8 +46,9 @@ public class OcelotEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.COD || item == Items.SALMON;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.OCELOT_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -37,11 +34,13 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -62,7 +61,8 @@ public class PandaEntity extends AnimalEntity {
|
|||
EntityEventPacket packet = new EntityEventPacket();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.setType(EntityEventType.EATING_ITEM);
|
||||
packet.setData(session.getItemMappings().getStoredItems().bamboo().getBedrockDefinition().getRuntimeId() << 16);
|
||||
// As of 1.20.5 - pandas can eat cake
|
||||
packet.setData(this.hand.getDefinition().getRuntimeId() << 16);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +89,9 @@ public class PandaEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.BAMBOO;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.PANDA_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,18 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -47,8 +47,9 @@ public class PigEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.CARROT || item == Items.POTATO || item == Items.BEETROOT;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.PIG_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -39,7 +40,8 @@ public class PolarBearEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return false;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.AbstractFishEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -67,7 +67,8 @@ public class RabbitEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.DANDELION || item == Items.CARROT || item == Items.GOLDEN_CARROT;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.RABBIT_FOOD;
|
||||
}
|
||||
}
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -36,8 +35,11 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -55,6 +57,12 @@ public class SheepEntity extends AnimalEntity {
|
|||
dirtyMetadata.put(EntityDataTypes.COLOR, (byte) color);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.SHEEP_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.SnifferState;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
|
@ -37,8 +35,11 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Tickable;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.SnifferState;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -71,8 +72,9 @@ public class SnifferEntity extends AnimalEntity implements Tickable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isSnifferFood(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.SNIFFER_FOOD;
|
||||
}
|
||||
|
||||
public void setSnifferState(ObjectEntityMetadata<SnifferState> entityMetadata) {
|
||||
|
|
|
@ -25,20 +25,20 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -94,8 +94,9 @@ public class StriderEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.WARPED_FUNGUS;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.STRIDER_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.AbstractFishEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -50,8 +50,9 @@ public class TurtleEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.SEAGRASS;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.TURTLE_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
|
@ -40,21 +39,16 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
|||
import org.geysermc.geyser.entity.type.living.animal.AnimalEntity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AbstractHorseEntity extends AnimalEntity {
|
||||
/**
|
||||
* A list of all foods a horse/donkey can eat on Java Edition.
|
||||
* Used to display interactive tag if needed.
|
||||
*/
|
||||
private static final Set<Item> DONKEY_AND_HORSE_FOODS = Set.of(Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE,
|
||||
Items.GOLDEN_CARROT, Items.SUGAR, Items.APPLE, Items.WHEAT, Items.HAY_BLOCK);
|
||||
|
||||
public AbstractHorseEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
@ -124,8 +118,9 @@ public class AbstractHorseEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return DONKEY_AND_HORSE_FOODS.contains(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.HORSE_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
|
@ -35,9 +33,11 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -90,8 +90,8 @@ public class CamelEntity extends AbstractHorseEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.CACTUS;
|
||||
protected @Nullable ItemTag getFoodTag() {
|
||||
return ItemTag.CAMEL_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,19 +25,24 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LlamaEntity extends ChestedHorseEntity {
|
||||
/**
|
||||
* Used to calculate inventory size
|
||||
*/
|
||||
@Getter
|
||||
private int strength = 1;
|
||||
|
||||
public LlamaEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
@ -45,32 +50,13 @@ public class LlamaEntity extends ChestedHorseEntity {
|
|||
dirtyMetadata.put(EntityDataTypes.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength
|
||||
}
|
||||
|
||||
/**
|
||||
* Color equipped on the llama
|
||||
*/
|
||||
public void setCarpetedColor(IntEntityMetadata entityMetadata) {
|
||||
// Bedrock treats llama decoration as armor
|
||||
MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket();
|
||||
equipmentPacket.setRuntimeEntityId(geyserId);
|
||||
// -1 means no armor
|
||||
int carpetIndex = entityMetadata.getPrimitiveValue();
|
||||
if (carpetIndex > -1 && carpetIndex <= 15) {
|
||||
// The damage value is the dye color that Java sends us, for pre-1.16.220
|
||||
// The item is always going to be a carpet
|
||||
equipmentPacket.setChestplate(session.getItemMappings().getCarpets().get(carpetIndex));
|
||||
} else {
|
||||
equipmentPacket.setChestplate(ItemData.AIR);
|
||||
}
|
||||
// Required to fill out the rest of the equipment or Bedrock ignores it, including above else statement if removing armor
|
||||
equipmentPacket.setBoots(ItemData.AIR);
|
||||
equipmentPacket.setHelmet(ItemData.AIR);
|
||||
equipmentPacket.setLeggings(ItemData.AIR);
|
||||
|
||||
session.sendUpstreamPacket(equipmentPacket);
|
||||
public void setStrength(IntEntityMetadata entityMetadata) {
|
||||
strength = MathUtils.constrain(entityMetadata.getPrimitiveValue(), 1, 5);
|
||||
this.dirtyMetadata.put(EntityDataTypes.STRENGTH, strength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.WHEAT || item == Items.HAY_BLOCK;
|
||||
protected @Nullable ItemTag getFoodTag() {
|
||||
return ItemTag.LLAMA_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue