SPIGOT-4833: Allow access to LivingEntity memories

This commit is contained in:
Yannick Lamprecht 2019-05-19 19:58:41 +10:00 committed by md_5
parent d06991d960
commit eb99127a36
4 changed files with 149 additions and 0 deletions

View file

@ -46,6 +46,8 @@ import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftEntityEquipment; import org.bukkit.craftbukkit.inventory.CraftEntityEquipment;
import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.potion.CraftPotionUtil; 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.AbstractArrow;
import org.bukkit.entity.DragonFireball; import org.bukkit.entity.DragonFireball;
import org.bukkit.entity.Egg; import org.bukkit.entity.Egg;
@ -69,6 +71,7 @@ import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.TippedArrow; import org.bukkit.entity.TippedArrow;
import org.bukkit.entity.Trident; import org.bukkit.entity.Trident;
import org.bukkit.entity.WitherSkull; import org.bukkit.entity.WitherSkull;
import org.bukkit.entity.memory.MemoryKey;
import org.bukkit.event.entity.EntityPotionEffectEvent; import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EntityEquipment;
@ -582,4 +585,14 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
public boolean isCollidable() { public boolean isCollidable() {
return getHandle().collides; return getHandle().collides;
} }
@Override
public <T> T getMemory(MemoryKey<T> memoryKey) {
return (T) getHandle().getBehaviorController().getMemory(CraftMemoryKey.fromMemoryKey(memoryKey)).map(CraftMemoryMapper::fromNms).orElse(null);
}
@Override
public <T> void setMemory(MemoryKey<T> memoryKey, T t) {
getHandle().getBehaviorController().setMemory(CraftMemoryKey.fromMemoryKey(memoryKey), CraftMemoryMapper.toNms(t));
}
} }

View file

@ -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 <T, U> MemoryModuleType<U> fromMemoryKey(MemoryKey<T> memoryKey) {
return (MemoryModuleType<U>) IRegistry.MEMORY_MODULE_TYPE.get(CraftNamespacedKey.toMinecraft(memoryKey.getKey()));
}
public static <T, U> MemoryKey<U> toMemoryKey(MemoryModuleType<T> memoryModuleType) {
return MemoryKey.getByKey(CraftNamespacedKey.fromMinecraft(IRegistry.MEMORY_MODULE_TYPE.getKey(memoryModuleType)));
}
}

View file

@ -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()));
}
}

View file

@ -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<GlobalPos> nmsHomeKey = CraftMemoryKey.fromMemoryKey(MemoryKey.HOME);
Assert.assertEquals("MemoryModuleType should be HOME", MemoryModuleType.HOME, nmsHomeKey);
}
@Test
public void shouldConvertBukkitJobSiteKeyToNMSRepresentation() {
MemoryModuleType<GlobalPos> nmsHomeKey = CraftMemoryKey.fromMemoryKey(MemoryKey.JOB_SITE);
Assert.assertEquals("MemoryModuleType should be JOB_SITE", MemoryModuleType.JOB_SITE, nmsHomeKey);
}
@Test
public void shouldConvertBukkitMeetingPointKeyToNMSRepresentation() {
MemoryModuleType<GlobalPos> nmsHomeKey = CraftMemoryKey.fromMemoryKey(MemoryKey.MEETING_POINT);
Assert.assertEquals("MemoryModuleType should be MEETING_POINT", MemoryModuleType.MEETING_POINT, nmsHomeKey);
}
@Test
public void shouldConvertNMSHomeKeyToBukkitRepresentation() {
MemoryKey<Location> bukkitHomeKey = CraftMemoryKey.toMemoryKey(MemoryModuleType.HOME);
Assert.assertEquals("MemoryModuleType should be HOME", MemoryKey.HOME, bukkitHomeKey);
}
@Test
public void shouldConvertNMSJobSiteKeyToBukkitRepresentation() {
MemoryKey<Location> bukkitJobSiteKey = CraftMemoryKey.toMemoryKey(MemoryModuleType.JOB_SITE);
Assert.assertEquals("MemoryKey should be JOB_SITE", MemoryKey.JOB_SITE, bukkitJobSiteKey);
}
@Test
public void shouldConvertNMSMeetingPointKeyToBukkitRepresentation() {
MemoryKey<Location> 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);
}
}
}
}