From eb99127a3637934a7b1dec0c9a3a9d71322fbf28 Mon Sep 17 00:00:00 2001 From: Yannick Lamprecht Date: Sun, 19 May 2019 19:58:41 +1000 Subject: [PATCH] SPIGOT-4833: Allow access to LivingEntity memories --- .../craftbukkit/entity/CraftLivingEntity.java | 13 ++++ .../entity/memory/CraftMemoryKey.java | 19 +++++ .../entity/memory/CraftMemoryMapper.java | 42 +++++++++++ .../entity/memory/CraftMemoryKeyTest.java | 75 +++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java create mode 100644 src/test/java/org/bukkit/entity/memory/CraftMemoryKeyTest.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index 46b3001439..2e007d4ffc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -46,6 +46,8 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftEntityEquipment; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.potion.CraftPotionUtil; +import org.bukkit.craftbukkit.entity.memory.CraftMemoryKey; +import org.bukkit.craftbukkit.entity.memory.CraftMemoryMapper; import org.bukkit.entity.AbstractArrow; import org.bukkit.entity.DragonFireball; import org.bukkit.entity.Egg; @@ -69,6 +71,7 @@ import org.bukkit.entity.ThrownPotion; import org.bukkit.entity.TippedArrow; import org.bukkit.entity.Trident; import org.bukkit.entity.WitherSkull; +import org.bukkit.entity.memory.MemoryKey; import org.bukkit.event.entity.EntityPotionEffectEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.EntityEquipment; @@ -582,4 +585,14 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public boolean isCollidable() { return getHandle().collides; } + + @Override + public T getMemory(MemoryKey memoryKey) { + return (T) getHandle().getBehaviorController().getMemory(CraftMemoryKey.fromMemoryKey(memoryKey)).map(CraftMemoryMapper::fromNms).orElse(null); + } + + @Override + public void setMemory(MemoryKey memoryKey, T t) { + getHandle().getBehaviorController().setMemory(CraftMemoryKey.fromMemoryKey(memoryKey), CraftMemoryMapper.toNms(t)); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java new file mode 100644 index 0000000000..fee6bc5882 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.entity.memory; + +import net.minecraft.server.IRegistry; +import net.minecraft.server.MemoryModuleType; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.memory.MemoryKey; + +public final class CraftMemoryKey { + + private CraftMemoryKey() {} + + public static MemoryModuleType fromMemoryKey(MemoryKey memoryKey) { + return (MemoryModuleType) IRegistry.MEMORY_MODULE_TYPE.get(CraftNamespacedKey.toMinecraft(memoryKey.getKey())); + } + + public static MemoryKey toMemoryKey(MemoryModuleType memoryModuleType) { + return MemoryKey.getByKey(CraftNamespacedKey.fromMinecraft(IRegistry.MEMORY_MODULE_TYPE.getKey(memoryModuleType))); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java new file mode 100644 index 0000000000..09a5961c68 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java @@ -0,0 +1,42 @@ +package org.bukkit.craftbukkit.entity.memory; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.GlobalPos; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; + +public final class CraftMemoryMapper { + + private CraftMemoryMapper() {} + + public static Object fromNms(Object object) { + if (object instanceof GlobalPos) { + return fromNms((GlobalPos) object); + } else if (object instanceof Long) { + return object; + } + + throw new UnsupportedOperationException("Do not know how to map " + object); + } + + public static Object toNms(Object object) { + if (object instanceof Location) { + return toNms((Location) object); + } + + throw new UnsupportedOperationException("Do not know how to map " + object); + } + + public static Location fromNms(GlobalPos globalPos) { + // PAIL: globalPos.a() -> getDimensionManager() + // PAIL: globalPos.b() -> getBlockPosition() + return new org.bukkit.Location(((CraftServer) Bukkit.getServer()).getServer().getWorldServer(globalPos.a()).getWorld(), globalPos.b().getX(), globalPos.b().getY(), globalPos.b().getZ()); + } + + public static GlobalPos toNms(Location location) { + // PAIL: GlobalPos.a(DmensionManager, BlockPosition) -> create() + return GlobalPos.a(((CraftWorld) location.getWorld()).getHandle().getWorldProvider().getDimensionManager(), new BlockPosition(location.getX(), location.getY(), location.getZ())); + } +} diff --git a/src/test/java/org/bukkit/entity/memory/CraftMemoryKeyTest.java b/src/test/java/org/bukkit/entity/memory/CraftMemoryKeyTest.java new file mode 100644 index 0000000000..491d9a6258 --- /dev/null +++ b/src/test/java/org/bukkit/entity/memory/CraftMemoryKeyTest.java @@ -0,0 +1,75 @@ +package org.bukkit.entity.memory; + +import net.minecraft.server.GlobalPos; +import net.minecraft.server.IRegistry; +import net.minecraft.server.MemoryModuleType; +import org.bukkit.Location; +import org.bukkit.craftbukkit.entity.memory.CraftMemoryKey; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Assert; +import org.junit.Test; + +public class CraftMemoryKeyTest extends AbstractTestingBase { + + @Test + public void shouldConvertBukkitHomeKeyToNMSRepresentation() { + MemoryModuleType nmsHomeKey = CraftMemoryKey.fromMemoryKey(MemoryKey.HOME); + Assert.assertEquals("MemoryModuleType should be HOME", MemoryModuleType.HOME, nmsHomeKey); + } + + @Test + public void shouldConvertBukkitJobSiteKeyToNMSRepresentation() { + MemoryModuleType nmsHomeKey = CraftMemoryKey.fromMemoryKey(MemoryKey.JOB_SITE); + Assert.assertEquals("MemoryModuleType should be JOB_SITE", MemoryModuleType.JOB_SITE, nmsHomeKey); + } + + @Test + public void shouldConvertBukkitMeetingPointKeyToNMSRepresentation() { + MemoryModuleType nmsHomeKey = CraftMemoryKey.fromMemoryKey(MemoryKey.MEETING_POINT); + Assert.assertEquals("MemoryModuleType should be MEETING_POINT", MemoryModuleType.MEETING_POINT, nmsHomeKey); + } + + @Test + public void shouldConvertNMSHomeKeyToBukkitRepresentation() { + MemoryKey bukkitHomeKey = CraftMemoryKey.toMemoryKey(MemoryModuleType.HOME); + Assert.assertEquals("MemoryModuleType should be HOME", MemoryKey.HOME, bukkitHomeKey); + } + + @Test + public void shouldConvertNMSJobSiteKeyToBukkitRepresentation() { + MemoryKey bukkitJobSiteKey = CraftMemoryKey.toMemoryKey(MemoryModuleType.JOB_SITE); + Assert.assertEquals("MemoryKey should be JOB_SITE", MemoryKey.JOB_SITE, bukkitJobSiteKey); + } + + @Test + public void shouldConvertNMSMeetingPointKeyToBukkitRepresentation() { + MemoryKey bukkitHomeKey = CraftMemoryKey.toMemoryKey(MemoryModuleType.MEETING_POINT); + Assert.assertEquals("MemoryKey should be MEETING_POINT", MemoryKey.MEETING_POINT, bukkitHomeKey); + } + + @Test + public void shouldReturnNullWhenBukkitRepresentationOfKeyisNotAvailable() { + MemoryKey bukkitNoKey = CraftMemoryKey.toMemoryKey(MemoryModuleType.MOBS); + Assert.assertNull("MemoryModuleType should be null", bukkitNoKey); + } + + @Test + public void shouldReturnNullWhenBukkitRepresentationOfKeyisNotAvailableAndSerializerIsNotPresent() { + for (MemoryModuleType memoryModuleType : IRegistry.MEMORY_MODULE_TYPE) { + if (!memoryModuleType.a().isPresent()) { // PAIL: a() -> getSerializer() + MemoryKey bukkitNoKey = CraftMemoryKey.toMemoryKey(memoryModuleType); + Assert.assertNull("MemoryModuleType should be null", bukkitNoKey); + } + } + } + + @Test + public void shouldReturnAnInstanceOfMemoryKeyWhenBukkitRepresentationOfKeyisAvailableAndSerializerIsPresent() { + for (MemoryModuleType memoryModuleType : IRegistry.MEMORY_MODULE_TYPE) { + if (memoryModuleType.a().isPresent()) { // PAIL: a() -> getSerializer() + MemoryKey bukkitNoKey = CraftMemoryKey.toMemoryKey(memoryModuleType); + Assert.assertNotNull("MemoryModuleType should not be null", bukkitNoKey); + } + } + } +}