diff --git a/Essentials/src/main/java/com/earth2me/essentials/messaging/IMessageRecipient.java b/Essentials/src/main/java/com/earth2me/essentials/messaging/IMessageRecipient.java index 1c2a13eba61..f1f6c91d025 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/messaging/IMessageRecipient.java +++ b/Essentials/src/main/java/com/earth2me/essentials/messaging/IMessageRecipient.java @@ -127,7 +127,12 @@ enum MessageResponse { * States that the message was NOT delivered as a result of the sender being muted. The message may * still have been shown to social spies. */ - SENDER_MUTED; + SENDER_MUTED, + /** + * States that the message was NOT received as a result of the recipient blocking incoming private + * messages via {@code essentials.chat.spy.exempt.block}. + */ + RECIPIENT_BLOCKED; /** * Returns whether this response is a success. In other words equal to {@link #SUCCESS} or {@link #SUCCESS_BUT_AFK} diff --git a/Essentials/src/main/java/com/earth2me/essentials/messaging/SimpleMessageRecipient.java b/Essentials/src/main/java/com/earth2me/essentials/messaging/SimpleMessageRecipient.java index d4a2e7473dc..1f055af24e4 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/messaging/SimpleMessageRecipient.java +++ b/Essentials/src/main/java/com/earth2me/essentials/messaging/SimpleMessageRecipient.java @@ -93,6 +93,17 @@ public MessageResponse sendMessage(final IMessageRecipient recipient, String mes message = preSendEvent.getMessage(); final User senderUser = getUser(this); + final User recipientUser = getUser(recipient); + // A recipient with essentials.chat.spy.exempt.block fully blocks incoming private messages, + // rather than merely being exempt from the socialspy broadcast. Since the message is never + // delivered, there is nothing for social spies to observe either. + // Note: PrivateMessageSentEvent is intentionally not fired here so the message is not relayed + // elsewhere (e.g. to Discord) as though it had actually been delivered. + if (recipientUser != null && recipientUser.isAuthorized("essentials.chat.spy.exempt.block")) { + sendTl("msgIgnore", recipient.getDisplayName()); + return MessageResponse.RECIPIENT_BLOCKED; + } + // A muted player must not have their message delivered to the recipient. However, social spies // may still observe the attempted message (see the socialspy-listen-muted-players setting). // Note: PrivateMessageSentEvent is intentionally not fired here so the message is not relayed @@ -142,6 +153,9 @@ public MessageResponse sendMessage(final IMessageRecipient recipient, String mes /** * Shows a private message to all online social spies, unless either party is exempt from being spied on. + *

+ * Note: a recipient holding {@code essentials.chat.spy.exempt.block} never reaches this method, since + * their message is blocked before delivery in {@link #sendMessage(IMessageRecipient, String)}. * * @param recipient the recipient of the private message * @param message the message that was sent @@ -162,7 +176,8 @@ private void sendSocialSpy(final IMessageRecipient recipient, final String messa if (senderUser == null // not null if player. || senderUser.isAuthorized("essentials.chat.spy.exempt") || recipientUser == null - || recipientUser.isAuthorized("essentials.chat.spy.exempt")) { + || recipientUser.isAuthorized("essentials.chat.spy.exempt") + || recipientUser.isAuthorized("essentials.chat.spy.exempt.block")) { return; } diff --git a/Essentials/src/main/resources/plugin.yml b/Essentials/src/main/resources/plugin.yml index 68496ebbbdf..a10f3bf448e 100644 --- a/Essentials/src/main/resources/plugin.yml +++ b/Essentials/src/main/resources/plugin.yml @@ -710,6 +710,8 @@ permissions: description: Allows the bearers to see all local chat messages, regardless of their proximity to the sender essentials.chat.spy.exempt: description: Allows the bearer to be exempt from the local chat spy permission + essentials.chat.spy.exempt.block: + description: Allows the bearer to fully block incoming private messages, in addition to being exempt from the local chat spy permission essentials.clearinventory: description: Allows access to the /clearinventory command essentials.clearinventory.all: