From 85591014c58d86d7116e386b95f669f46ff4b950 Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Wed, 24 Apr 2024 01:15:00 +1000 Subject: [PATCH] #1378: Add methods to convert between an entity and a SNBT string By: Jishuna --- .../org/bukkit/craftbukkit/CraftServer.java | 7 +++ .../craftbukkit/entity/CraftEntity.java | 10 +++++ .../entity/CraftEntityFactory.java | 44 +++++++++++++++++++ .../entity/CraftEntitySnapshot.java | 5 +++ 4 files changed, 66 insertions(+) create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index a0fe9dd313..d1d13683a4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -157,6 +157,7 @@ import org.bukkit.craftbukkit.boss.CraftKeyedBossbar; import org.bukkit.craftbukkit.command.BukkitCommandWrapper; import org.bukkit.craftbukkit.command.CraftCommandMap; import org.bukkit.craftbukkit.command.VanillaCommandWrapper; +import org.bukkit.craftbukkit.entity.CraftEntityFactory; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.generator.CraftWorldInfo; @@ -305,6 +306,7 @@ public final class CraftServer implements Server { ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); ConfigurationSerialization.registerClass(CraftPlayerProfile.class); CraftItemFactory.instance(); + CraftEntityFactory.instance(); } public CraftServer(DedicatedServer console, PlayerList playerList) { @@ -2179,6 +2181,11 @@ public final class CraftServer implements Server { return CraftItemFactory.instance(); } + @Override + public CraftEntityFactory getEntityFactory() { + return CraftEntityFactory.instance(); + } + @Override public CraftScoreboardManager getScoreboardManager() { return scoreboardManager; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index d19210e115..f5b6b5cd24 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -780,6 +780,16 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().inWorld; } + @Override + public String getAsString() { + NBTTagCompound tag = new NBTTagCompound(); + if (!getHandle().saveAsPassenger(tag, false)) { + return null; + } + + return tag.getAsString(); + } + @Override public EntitySnapshot createSnapshot() { return CraftEntitySnapshot.create(this); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java new file mode 100644 index 0000000000..caa492d9bd --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java @@ -0,0 +1,44 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.nbt.MojangsonParser; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.entity.EntityTypes; +import org.bukkit.entity.EntityFactory; +import org.bukkit.entity.EntitySnapshot; + +public class CraftEntityFactory implements EntityFactory { + + private static final CraftEntityFactory instance; + + static { + instance = new CraftEntityFactory(); + } + + private CraftEntityFactory() { + } + + @Override + public EntitySnapshot createEntitySnapshot(String input) { + Preconditions.checkArgument(input != null, "Input string cannot be null"); + + NBTTagCompound tag; + try { + tag = MojangsonParser.parseTag(input); + } catch (CommandSyntaxException e) { + throw new IllegalArgumentException("Could not parse Entity: " + input, e); + } + + EntityTypes type = EntityTypes.by(tag).orElse(null); + if (type == null) { + throw new IllegalArgumentException("Could not parse Entity: " + input); + } + + return CraftEntitySnapshot.create(tag, CraftEntityType.minecraftToBukkit(type)); + } + + public static CraftEntityFactory instance() { + return instance; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java index 2c133e8fa8..79c56e731a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java @@ -42,6 +42,11 @@ public class CraftEntitySnapshot implements EntitySnapshot { return location.getWorld().addEntity(internal.getBukkitEntity()); } + @Override + public String getAsString() { + return data.getAsString(); + } + private net.minecraft.world.entity.Entity createInternal(World world) { net.minecraft.world.level.World nms = ((CraftWorld) world).getHandle(); net.minecraft.world.entity.Entity internal = EntityTypes.loadEntityRecursive(data, nms, Function.identity());