diff --git a/game/src/main/org/apollo/game/message/handler/ItemOnObjectVerificationHandler.java b/game/src/main/org/apollo/game/message/handler/ItemOnObjectVerificationHandler.java index 9d17cc08..89a9260c 100644 --- a/game/src/main/org/apollo/game/message/handler/ItemOnObjectVerificationHandler.java +++ b/game/src/main/org/apollo/game/message/handler/ItemOnObjectVerificationHandler.java @@ -1,13 +1,20 @@ package org.apollo.game.message.handler; +import org.apollo.cache.def.ObjectDefinition; import org.apollo.game.message.impl.ItemOnObjectMessage; import org.apollo.game.model.Item; +import org.apollo.game.model.Position; import org.apollo.game.model.World; +import org.apollo.game.model.area.Region; +import org.apollo.game.model.entity.EntityType; import org.apollo.game.model.entity.Player; +import org.apollo.game.model.entity.obj.GameObject; import org.apollo.game.model.inter.bank.BankConstants; import org.apollo.game.model.inv.Inventory; import org.apollo.game.model.inv.SynchronizationInventoryListener; +import java.util.Set; + /** * A {@link MessageHandler} that verifies {@link ItemOnObjectMessage}s. * @@ -44,6 +51,21 @@ public final class ItemOnObjectVerificationHandler extends MessageHandler= ObjectDefinition.count()) { + message.terminate(); + return; + } + + Position position = message.getPosition(); + Region region = world.getRegionRepository().fromPosition(position); + Set objects = region.getEntities(position, EntityType.STATIC_OBJECT, EntityType.DYNAMIC_OBJECT); + + if (!player.getPosition().isWithinDistance(position, 15) || !ObjectActionVerificationHandler.containsObject(objectId, objects)) { + message.terminate(); + return; + } } } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/message/handler/ObjectActionVerificationHandler.java b/game/src/main/org/apollo/game/message/handler/ObjectActionVerificationHandler.java index 862f59a9..8983cee0 100644 --- a/game/src/main/org/apollo/game/message/handler/ObjectActionVerificationHandler.java +++ b/game/src/main/org/apollo/game/message/handler/ObjectActionVerificationHandler.java @@ -26,7 +26,7 @@ public final class ObjectActionVerificationHandler extends MessageHandler objects) { + public static boolean containsObject(int id, Set objects) { return objects.stream().anyMatch(object -> object.getId() == id); } diff --git a/game/src/test/org/apollo/game/message/handler/ItemOnObjectVerificationHandlerTest.java b/game/src/test/org/apollo/game/message/handler/ItemOnObjectVerificationHandlerTest.java new file mode 100644 index 00000000..0f391776 --- /dev/null +++ b/game/src/test/org/apollo/game/message/handler/ItemOnObjectVerificationHandlerTest.java @@ -0,0 +1,135 @@ +package org.apollo.game.message.handler; + +import org.apollo.cache.def.ItemDefinition; +import org.apollo.cache.def.ObjectDefinition; +import org.apollo.game.message.impl.ItemOnObjectMessage; +import org.apollo.game.model.Item; +import org.apollo.game.model.Position; +import org.apollo.game.model.World; +import org.apollo.game.model.area.Region; +import org.apollo.game.model.area.RegionRepository; +import org.apollo.game.model.entity.Entity; +import org.apollo.game.model.entity.EntityType; +import org.apollo.game.model.entity.Player; +import org.apollo.game.model.entity.obj.StaticGameObject; +import org.apollo.game.model.inter.bank.BankConstants; +import org.apollo.game.model.inv.Inventory; +import org.apollo.game.model.inv.SynchronizationInventoryListener; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertTrue; +import static org.powermock.api.mockito.PowerMockito.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({Player.class, World.class, Region.class, RegionRepository.class, ObjectDefinition.class, + ItemDefinition.class}) +public class ItemOnObjectVerificationHandlerTest { + + @Before + public void setupTestItemDefinitions() { + mockStatic(ItemDefinition.class); + when(ItemDefinition.lookup(4151)).thenReturn(new ItemDefinition(4151)); + + mockStatic(ObjectDefinition.class); + when(ObjectDefinition.count()).thenReturn(2); + } + + + @Test + public void testTerminateIfInvalidItem() throws Exception { + Position playerPosition = new Position(3200, 3200); + Position objectPosition = new Position(3200, 3216); + + World world = mock(World.class); + Region region = mock(Region.class); + RegionRepository regionRepository = mock(RegionRepository.class); + Player player = mock(Player.class); + + Set entitySet = new HashSet<>(); + entitySet.add(new StaticGameObject(world, 4151, objectPosition, 0, 0)); + Inventory inventory = new Inventory(28); + + when(player.getInventory()).thenReturn(inventory); + when(world.getRegionRepository()).thenReturn(regionRepository); + when(regionRepository.fromPosition(objectPosition)).thenReturn(region); + when(player.getPosition()).thenReturn(playerPosition); + when(region.getEntities(objectPosition, EntityType.STATIC_OBJECT, EntityType.DYNAMIC_OBJECT)) + .thenReturn(entitySet); + + ItemOnObjectMessage itemOnObjectMessage = new ItemOnObjectMessage(SynchronizationInventoryListener.INVENTORY_ID, 4151, 1, + 1, objectPosition.getX(), objectPosition.getY()); + ItemOnObjectVerificationHandler itemOnObjectVerificationHandler = new ItemOnObjectVerificationHandler(world); + + itemOnObjectVerificationHandler.handle(player, itemOnObjectMessage); + + assertTrue("ObjectVerificationHandler: message not terminated valid item given!", itemOnObjectMessage.terminated()); + } + + @Test + public void testTerminateIfInvalidSlot() throws Exception { + Position playerPosition = new Position(3200, 3200); + Position objectPosition = new Position(3200, 3200); + + World world = mock(World.class); + Region region = mock(Region.class); + RegionRepository regionRepository = mock(RegionRepository.class); + Player player = mock(Player.class); + + Set entitySet = new HashSet<>(); + entitySet.add(new StaticGameObject(world, 4151, objectPosition, 0, 0)); + Inventory inventory = new Inventory(28); + + when(player.getInventory()).thenReturn(inventory); + when(world.getRegionRepository()).thenReturn(regionRepository); + when(regionRepository.fromPosition(objectPosition)).thenReturn(region); + when(player.getPosition()).thenReturn(playerPosition); + when(region.getEntities(objectPosition, EntityType.STATIC_OBJECT, EntityType.DYNAMIC_OBJECT)) + .thenReturn(entitySet); + + ItemOnObjectMessage itemOnObjectMessage = new ItemOnObjectMessage(SynchronizationInventoryListener.INVENTORY_ID, 4151, 30, + 1, objectPosition.getX(), objectPosition.getY()); + ItemOnObjectVerificationHandler itemOnObjectVerificationHandler = new ItemOnObjectVerificationHandler(world); + + itemOnObjectVerificationHandler.handle(player, itemOnObjectMessage); + + assertTrue("ObjectVerificationHandler: message not terminated when no valid slot given!", itemOnObjectMessage.terminated()); + } + + @Test + public void testTerminateIfObjectOutOfRange() throws Exception { + Position playerPosition = new Position(3200, 3200); + Position objectPosition = new Position(3200, 3200); + + World world = mock(World.class); + Region region = mock(Region.class); + RegionRepository regionRepository = mock(RegionRepository.class); + Player player = mock(Player.class); + + Set entitySet = new HashSet<>(); + entitySet.add(new StaticGameObject(world, 4151, objectPosition, 0, 0)); + Inventory inventory = new Inventory(28); + inventory.set(1, new Item(4151, 1)); + + when(player.getInventory()).thenReturn(inventory); + when(world.getRegionRepository()).thenReturn(regionRepository); + when(regionRepository.fromPosition(objectPosition)).thenReturn(region); + when(player.getPosition()).thenReturn(playerPosition); + when(region.getEntities(objectPosition, EntityType.STATIC_OBJECT, EntityType.DYNAMIC_OBJECT)) + .thenReturn(entitySet); + + ItemOnObjectMessage itemOnObjectMessage = new ItemOnObjectMessage(SynchronizationInventoryListener.INVENTORY_ID, 4151, 1, + 1, objectPosition.getX(), objectPosition.getY()); + ItemOnObjectVerificationHandler itemOnObjectVerificationHandler = new ItemOnObjectVerificationHandler(world); + + itemOnObjectVerificationHandler.handle(player, itemOnObjectMessage); + + assertTrue("ObjectVerificationHandler: message not terminated when object out of range!", itemOnObjectMessage.terminated()); + } +} \ No newline at end of file