From d9c34cd9ed75717ef65a1aa06ec3d67eb6da9ea1 Mon Sep 17 00:00:00 2001 From: Major- Date: Mon, 24 Aug 2015 13:38:54 +0100 Subject: [PATCH] Allow interception at any level in the message class hierarchy. --- data/messages.xml | 218 +++++++++--------- .../handler/ItemVerificationHandler.java | 18 +- .../message/handler/MessageHandlerChain.java | 7 +- .../handler/MessageHandlerChainSet.java | 46 +++- .../message/impl/InventoryItemMessage.java | 29 ++- .../game/message/impl/ItemActionMessage.java | 6 +- .../game/message/impl/ItemOnItemMessage.java | 4 +- .../message/impl/ItemOnObjectMessage.java | 4 +- .../game/message/impl/ItemOptionMessage.java | 6 +- .../game/message/impl/MagicOnItemMessage.java | 4 +- .../r317/RemoveObjectMessageEncoder.java | 1 - .../apollo/game/release/r377/Release377.java | 2 +- ....java => SetWidgetTextMessageEncoder.java} | 2 +- .../org/apollo/game/session/GameSession.java | 11 +- .../task/PrePlayerSynchronizationTask.java | 5 - 15 files changed, 205 insertions(+), 158 deletions(-) rename game/src/main/org/apollo/game/release/r377/{SetWidgetTexMessageEncoder.java => SetWidgetTextMessageEncoder.java} (90%) diff --git a/data/messages.xml b/data/messages.xml index f24b2420..1f5113d4 100644 --- a/data/messages.xml +++ b/data/messages.xml @@ -1,111 +1,111 @@ - - org.apollo.game.message.impl.ButtonMessage - - org.apollo.game.message.handler.DialogueButtonHandler - org.apollo.game.message.handler.BankButtonMessageHandler - - - - org.apollo.game.message.impl.ChatMessage - - org.apollo.game.message.handler.ChatVerificationHandler - org.apollo.game.message.handler.ChatMessageHandler - - - - org.apollo.game.message.impl.ClosedInterfaceMessage - - org.apollo.game.message.handler.ClosedInterfaceMessageHandler - - - - org.apollo.game.message.impl.CommandMessage - - org.apollo.game.message.handler.CommandMessageHandler - - - - org.apollo.game.message.impl.DialogueContinueMessage - - org.apollo.game.message.handler.DialogueContinueMessageHandler - - - - org.apollo.game.message.impl.EnteredAmountMessage - - org.apollo.game.message.handler.EnteredAmountMessageHandler - - - - org.apollo.game.message.impl.ItemActionMessage - - org.apollo.game.message.handler.ItemVerificationHandler - org.apollo.game.message.handler.RemoveEquippedItemHandler - org.apollo.game.message.handler.BankMessageHandler - - - - org.apollo.game.message.impl.ItemOnItemMessage - - org.apollo.game.message.handler.ItemVerificationHandler - org.apollo.game.message.handler.ItemOnItemVerificationHandler - - - - org.apollo.game.message.impl.ItemOnObjectMessage - - org.apollo.game.message.handler.ItemOnObjectVerificationHandler - - - - org.apollo.game.message.impl.InventoryItemMessage - - org.apollo.game.message.handler.ItemVerificationHandler - org.apollo.game.message.handler.EquipItemHandler - - - - org.apollo.game.message.impl.MagicOnItemMessage - - org.apollo.game.message.handler.ItemVerificationHandler - - - - org.apollo.game.message.impl.NpcActionMessage - - org.apollo.game.message.handler.NpcActionVerificationHandler - - - - org.apollo.game.message.impl.ObjectActionMessage - - org.apollo.game.message.handler.ObjectActionVerificationHandler - - - - org.apollo.game.message.impl.PlayerActionMessage - - org.apollo.game.message.handler.PlayerActionVerificationHandler - - - - org.apollo.game.message.impl.PlayerDesignMessage - - org.apollo.game.message.handler.PlayerDesignVerificationHandler - org.apollo.game.message.handler.PlayerDesignMessageHandler - - - - org.apollo.game.message.impl.SwitchItemMessage - - org.apollo.game.message.handler.SwitchItemMessageHandler - - - - org.apollo.game.message.impl.WalkMessage - - org.apollo.game.message.handler.WalkMessageHandler - - + + org.apollo.game.message.impl.ButtonMessage + + org.apollo.game.message.handler.DialogueButtonHandler + org.apollo.game.message.handler.BankButtonMessageHandler + + + + org.apollo.game.message.impl.ChatMessage + + org.apollo.game.message.handler.ChatVerificationHandler + org.apollo.game.message.handler.ChatMessageHandler + + + + org.apollo.game.message.impl.ClosedInterfaceMessage + + org.apollo.game.message.handler.ClosedInterfaceMessageHandler + + + + org.apollo.game.message.impl.CommandMessage + + org.apollo.game.message.handler.CommandMessageHandler + + + + org.apollo.game.message.impl.DialogueContinueMessage + + org.apollo.game.message.handler.DialogueContinueMessageHandler + + + + org.apollo.game.message.impl.EnteredAmountMessage + + org.apollo.game.message.handler.EnteredAmountMessageHandler + + + + org.apollo.game.message.impl.ItemActionMessage + + org.apollo.game.message.handler.ItemVerificationHandler + org.apollo.game.message.handler.RemoveEquippedItemHandler + org.apollo.game.message.handler.BankMessageHandler + + + + org.apollo.game.message.impl.ItemOnItemMessage + + org.apollo.game.message.handler.ItemVerificationHandler + org.apollo.game.message.handler.ItemOnItemVerificationHandler + + + + org.apollo.game.message.impl.ItemOnObjectMessage + + org.apollo.game.message.handler.ItemOnObjectVerificationHandler + + + + org.apollo.game.message.impl.ItemOptionMessage + + org.apollo.game.message.handler.ItemVerificationHandler + org.apollo.game.message.handler.EquipItemHandler + + + + org.apollo.game.message.impl.MagicOnItemMessage + + org.apollo.game.message.handler.ItemVerificationHandler + + + + org.apollo.game.message.impl.NpcActionMessage + + org.apollo.game.message.handler.NpcActionVerificationHandler + + + + org.apollo.game.message.impl.ObjectActionMessage + + org.apollo.game.message.handler.ObjectActionVerificationHandler + + + + org.apollo.game.message.impl.PlayerActionMessage + + org.apollo.game.message.handler.PlayerActionVerificationHandler + + + + org.apollo.game.message.impl.PlayerDesignMessage + + org.apollo.game.message.handler.PlayerDesignVerificationHandler + org.apollo.game.message.handler.PlayerDesignMessageHandler + + + + org.apollo.game.message.impl.SwitchItemMessage + + org.apollo.game.message.handler.SwitchItemMessageHandler + + + + org.apollo.game.message.impl.WalkMessage + + org.apollo.game.message.handler.WalkMessageHandler + + diff --git a/game/src/main/org/apollo/game/message/handler/ItemVerificationHandler.java b/game/src/main/org/apollo/game/message/handler/ItemVerificationHandler.java index a06095e0..178417e6 100644 --- a/game/src/main/org/apollo/game/message/handler/ItemVerificationHandler.java +++ b/game/src/main/org/apollo/game/message/handler/ItemVerificationHandler.java @@ -19,15 +19,6 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener; */ public final class ItemVerificationHandler extends MessageHandler { - /** - * Creates the ItemVerificationHandler. - * - * @param world The {@link World} the {@link InventoryItemMessage} occurred in. - */ - public ItemVerificationHandler(World world) { - super(world); - } - /** * A supplier for an {@link Inventory}. * @@ -69,6 +60,15 @@ public final class ItemVerificationHandler extends MessageHandler The Message type this chain represents. * @author Graham * @author Ryley - * @param The Message type this chain represents. */ public final class MessageHandlerChain { /** - * The handlers. + * The List of MessageHandlers. */ private final List> handlers = new ArrayList<>(); @@ -50,8 +50,7 @@ public final class MessageHandlerChain { * * @param player The Player to handle this message for. * @param message The Message. - * @return {@code true} if and only if the Message propagated down the chain without being terminated, otherwise - * {@code false}. + * @return {@code true} iff the Message propagated down the chain without being terminated. */ public boolean notify(Player player, M message) { for (MessageHandler handler : handlers) { diff --git a/game/src/main/org/apollo/game/message/handler/MessageHandlerChainSet.java b/game/src/main/org/apollo/game/message/handler/MessageHandlerChainSet.java index 7c6a5625..11c466e1 100644 --- a/game/src/main/org/apollo/game/message/handler/MessageHandlerChainSet.java +++ b/game/src/main/org/apollo/game/message/handler/MessageHandlerChainSet.java @@ -1,5 +1,7 @@ package org.apollo.game.message.handler; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.HashMap; import java.util.Map; @@ -16,27 +18,36 @@ import org.apollo.net.message.Message; public final class MessageHandlerChainSet { /** - * The {@link Map} of Message types to {@link MessageHandlerChain}s + * The {@link Map} of {@link Message} {@link Class} types to {@link MessageHandlerChain}s */ private final Map, MessageHandlerChain> chains = new HashMap<>(); + /** + * The {@link Map} of {@link Message} {@link Class} types to {@link Deque}s of all Classes in the chain. + */ + private final Map, Deque>> classes = new HashMap<>(); + /** * Notifies the appropriate {@link MessageHandlerChain} that a {@link Message} has been received. * * @param player The {@link Player} receiving the Message. * @param message The Message. - * @return {@code true} if the Message propagated down the chain without being terminated or if the chain for the - * Message was not found, otherwise {@code false}. + * @return {@code true} iff the Message propagated down the chain without being terminated. */ @SuppressWarnings("unchecked") public boolean notify(Player player, M message) { - Class clazz = (Class) message.getClass(); - while (clazz.getSuperclass() != Message.class) { - clazz = (Class) clazz.getSuperclass(); + Deque> classes = this.classes.computeIfAbsent(message.getClass(), + this::getMessageClasses); + + for (Class type : classes) { + MessageHandlerChain chain = (MessageHandlerChain) chains.get(type); + + if (chain != null && !chain.notify(player, message)) { + return false; + } } - MessageHandlerChain chain = (MessageHandlerChain) chains.computeIfAbsent(clazz, MessageHandlerChain::new); - return chain.notify(player, message); + return true; } /** @@ -51,4 +62,23 @@ public final class MessageHandlerChainSet { chain.addHandler((MessageHandler) handler); } + /** + * Gets the {@link Deque} of {@link Class}es that can be handled. + * + * @param type The Class type of the message. Must not be the Class for {@link Message} itself. + * @return The Deque of Classes. Will never be {@code null}. + */ + @SuppressWarnings("unchecked") + private Deque> getMessageClasses(Class type) { + Deque> classes = new ArrayDeque<>(); + Class clazz = type; + + do { + classes.addFirst((Class) clazz); + clazz = clazz.getSuperclass(); + } while (clazz != Message.class); + + return classes; + } + } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/message/impl/InventoryItemMessage.java b/game/src/main/org/apollo/game/message/impl/InventoryItemMessage.java index 1be17e45..9419c4c3 100644 --- a/game/src/main/org/apollo/game/message/impl/InventoryItemMessage.java +++ b/game/src/main/org/apollo/game/message/impl/InventoryItemMessage.java @@ -1,10 +1,13 @@ package org.apollo.game.message.impl; +import com.google.common.base.Preconditions; import org.apollo.net.message.Message; +import java.util.NoSuchElementException; +import java.util.OptionalInt; + /** - * A {@link Message} that represents some sort of action on an item in an inventory. Note that this is the parent of - * both item option and item action message, and so cannot be used to determine when one of those messages is fired. + * A {@link Message} that represents some sort of action on an item in an inventory. * * @author Chris Fletcher */ @@ -21,9 +24,9 @@ public abstract class InventoryItemMessage extends Message { private final int interfaceId; /** - * The option number (1-5). + * The option number (1-5 if present). */ - private final int option; + private final OptionalInt option; /** * The item's slot. @@ -31,14 +34,14 @@ public abstract class InventoryItemMessage extends Message { private final int slot; /** - * Creates the item action message. + * Creates the InventoryItemMessage. * - * @param option The option number. + * @param option The option number, if applicable. * @param interfaceId The interface id. * @param id The id. * @param slot The slot. */ - protected InventoryItemMessage(int option, int interfaceId, int id, int slot) { + protected InventoryItemMessage(OptionalInt option, int interfaceId, int id, int slot) { this.option = option; this.interfaceId = interfaceId; this.id = id; @@ -67,9 +70,10 @@ public abstract class InventoryItemMessage extends Message { * Gets the option number. * * @return The option number. + * @throws NoSuchElementException If there is no option. */ public final int getOption() { - return option; + return option.getAsInt(); } /** @@ -81,4 +85,13 @@ public abstract class InventoryItemMessage extends Message { return slot; } + /** + * Returns whether or not this InventoryItemMessage has an option number. + * + * @return {@code true} iff this InventoryItemMessage has an option number. + */ + public final boolean hasOption() { + return option.isPresent(); + } + } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/message/impl/ItemActionMessage.java b/game/src/main/org/apollo/game/message/impl/ItemActionMessage.java index ba4f327b..7f0cf430 100644 --- a/game/src/main/org/apollo/game/message/impl/ItemActionMessage.java +++ b/game/src/main/org/apollo/game/message/impl/ItemActionMessage.java @@ -2,6 +2,8 @@ package org.apollo.game.message.impl; import org.apollo.net.message.Message; +import java.util.OptionalInt; + /** * A {@link Message} sent by the client that represents some sort of action on an item. Note that the actual message * sent by the client is one of the five item action messages, but this is the message that should be intercepted (and @@ -12,7 +14,7 @@ import org.apollo.net.message.Message; public abstract class ItemActionMessage extends InventoryItemMessage { /** - * Creates the item action message. + * Creates the ItemActionMessage. * * @param option The option number. * @param interfaceId The interface id. @@ -20,7 +22,7 @@ public abstract class ItemActionMessage extends InventoryItemMessage { * @param slot The slot. */ public ItemActionMessage(int option, int interfaceId, int id, int slot) { - super(option, interfaceId, id, slot); + super(OptionalInt.of(option), interfaceId, id, slot); } } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/message/impl/ItemOnItemMessage.java b/game/src/main/org/apollo/game/message/impl/ItemOnItemMessage.java index 164595fb..017b2e6c 100644 --- a/game/src/main/org/apollo/game/message/impl/ItemOnItemMessage.java +++ b/game/src/main/org/apollo/game/message/impl/ItemOnItemMessage.java @@ -1,5 +1,7 @@ package org.apollo.game.message.impl; +import java.util.OptionalInt; + /** * A {@link InventoryItemMessage} sent by the client when a player uses one inventory item on another. * @@ -33,7 +35,7 @@ public final class ItemOnItemMessage extends InventoryItemMessage { * @param targetSlot The slot of the target item. */ public ItemOnItemMessage(int usedInterface, int usedId, int usedSlot, int targetInterface, int targetId, int targetSlot) { - super(0, usedInterface, usedId, usedSlot); + super(OptionalInt.empty(), usedInterface, usedId, usedSlot); this.targetInterface = targetInterface; this.targetSlot = targetSlot; this.targetId = targetId; diff --git a/game/src/main/org/apollo/game/message/impl/ItemOnObjectMessage.java b/game/src/main/org/apollo/game/message/impl/ItemOnObjectMessage.java index 4884fa3b..fabc2854 100644 --- a/game/src/main/org/apollo/game/message/impl/ItemOnObjectMessage.java +++ b/game/src/main/org/apollo/game/message/impl/ItemOnObjectMessage.java @@ -3,6 +3,8 @@ package org.apollo.game.message.impl; import org.apollo.game.model.Position; import org.apollo.net.message.Message; +import java.util.OptionalInt; + /** * A {@link Message} sent by the client when an item is used on an object. * @@ -31,7 +33,7 @@ public final class ItemOnObjectMessage extends InventoryItemMessage { * @param y The y coordinate. */ public ItemOnObjectMessage(int interfaceId, int itemId, int itemSlot, int objectId, int x, int y) { - super(0, interfaceId, itemId, itemSlot); + super(OptionalInt.empty(), interfaceId, itemId, itemSlot); this.objectId = objectId; position = new Position(x, y); } diff --git a/game/src/main/org/apollo/game/message/impl/ItemOptionMessage.java b/game/src/main/org/apollo/game/message/impl/ItemOptionMessage.java index 3a7641df..2de16f25 100644 --- a/game/src/main/org/apollo/game/message/impl/ItemOptionMessage.java +++ b/game/src/main/org/apollo/game/message/impl/ItemOptionMessage.java @@ -1,5 +1,7 @@ package org.apollo.game.message.impl; +import java.util.OptionalInt; + /** * An {@link InventoryItemMessage} sent by the client when an item's option is clicked (e.g. equip, eat, drink, etc). * Note that the actual message sent by the client is one of the five item option messages, but this is the message that @@ -10,7 +12,7 @@ package org.apollo.game.message.impl; public abstract class ItemOptionMessage extends InventoryItemMessage { /** - * Creates the item option message. + * Creates the ItemOptionMessage. * * @param option The option number. * @param interfaceId The interface id. @@ -18,7 +20,7 @@ public abstract class ItemOptionMessage extends InventoryItemMessage { * @param slot The slot. */ public ItemOptionMessage(int option, int interfaceId, int id, int slot) { - super(option, interfaceId, id, slot); + super(OptionalInt.of(option), interfaceId, id, slot); } } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/message/impl/MagicOnItemMessage.java b/game/src/main/org/apollo/game/message/impl/MagicOnItemMessage.java index 75ee2767..52106090 100644 --- a/game/src/main/org/apollo/game/message/impl/MagicOnItemMessage.java +++ b/game/src/main/org/apollo/game/message/impl/MagicOnItemMessage.java @@ -1,5 +1,7 @@ package org.apollo.game.message.impl; +import java.util.OptionalInt; + /** * A {@link InventoryItemMessage} sent by the client when a player casts a spell on an inventory item. * @@ -21,7 +23,7 @@ public final class MagicOnItemMessage extends InventoryItemMessage { * @param spell The spell id. */ public MagicOnItemMessage(int interfaceId, int id, int slot, int spell) { - super(0, interfaceId, id, slot); + super(OptionalInt.empty(), interfaceId, id, slot); this.spell = spell; } diff --git a/game/src/main/org/apollo/game/release/r317/RemoveObjectMessageEncoder.java b/game/src/main/org/apollo/game/release/r317/RemoveObjectMessageEncoder.java index 92f26119..61dc247c 100644 --- a/game/src/main/org/apollo/game/release/r317/RemoveObjectMessageEncoder.java +++ b/game/src/main/org/apollo/game/release/r317/RemoveObjectMessageEncoder.java @@ -20,7 +20,6 @@ public final class RemoveObjectMessageEncoder extends MessageEncoder 0) { - System.out.println("Sending in mode " + mode + ", new regions=" + newRegions); - - } - messages.forEach(player::send); }