From ac52342b171bfaf0ba3d7ca5439fbcf0f8e1b8df Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Mon, 15 Sep 2003 21:11:40 +0000 Subject: [PATCH] - Refactored ChatValidator into ChatFilter, which can invalidate a message by returning null instead of a filtered version. - Changed the MuteDirector to implement ChatFilter. - ChatDirector no longer needs a reference to the MuteDirector because the outgoing mute-checking is now handled by the standard filtering code. - Fixed a bug introduced by Walter back in December that caused the MuteDirector to be _removed_ as a validator the first time you try to /tell to a player that you've muted. How we never detected this, I'll stay awake at night wondering... git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2795 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../crowd/chat/client/ChatDirector.java | 124 ++++++++---------- .../crowd/chat/client/ChatFilter.java | 22 ++++ .../crowd/chat/client/ChatValidator.java | 22 ---- .../crowd/chat/client/MuteDirector.java | 31 +++-- 4 files changed, 92 insertions(+), 107 deletions(-) create mode 100644 src/java/com/threerings/crowd/chat/client/ChatFilter.java delete mode 100644 src/java/com/threerings/crowd/chat/client/ChatValidator.java diff --git a/src/java/com/threerings/crowd/chat/client/ChatDirector.java b/src/java/com/threerings/crowd/chat/client/ChatDirector.java index 0258912cd..a80c5c397 100644 --- a/src/java/com/threerings/crowd/chat/client/ChatDirector.java +++ b/src/java/com/threerings/crowd/chat/client/ChatDirector.java @@ -1,5 +1,5 @@ // -// $Id: ChatDirector.java,v 1.47 2003/06/26 19:57:24 mdb Exp $ +// $Id: ChatDirector.java,v 1.48 2003/09/15 21:11:40 ray Exp $ package com.threerings.crowd.chat.client; @@ -83,17 +83,6 @@ public class ChatDirector extends BasicDirector _ctx.getLocationDirector().addLocationObserver(this); } - /** - * Sets the mute director, if one is desired. - */ - public void setMuteDirector (MuteDirector muter) - { - if (_muter == null) { - _muter = muter; - _muter.setChatDirector(this); - } - } - /** * Adds the supplied chat display to the chat display list. It will * subsequently be notified of incoming chat messages as well as tell @@ -114,21 +103,21 @@ public class ChatDirector extends BasicDirector } /** - * Adds the specified chat validator to the list of validators. All - * chat requests will be validated with all validators before they may - * be accepted. + * Adds the specified chat filter to the list of filters. All + * chat requests and receipts will be filtered with all filters + * before they being sent or dispatched locally. */ - public void addChatValidator (ChatValidator validator) + public void addChatFilter (ChatFilter filter) { - _validators.add(validator); + _filters.add(filter); } /** * Removes the specified chat validator from the list of chat validators. */ - public void removeChatValidator (ChatValidator validator) + public void removeChatFilter (ChatFilter filter) { - _validators.remove(validator); + _filters.remove(filter); } /** @@ -317,9 +306,8 @@ public class ChatDirector extends BasicDirector SpeakService speakService, String message, byte mode) { // make sure they can say what they want to say - _validateMessageOp.setMessage(message); - _validators.apply(_validateMessageOp); - if (!_validateMessageOp.isValid()) { + message = filter(message, null, true); + if (message == null) { return; } @@ -334,6 +322,13 @@ public class ChatDirector extends BasicDirector */ public void requestBroadcast (String message) { + message = filter(message, null, true); + if (message == null) { + displayFeedback(_bundle, + MessageBundle.compose("m.broadcast_failed", "m.filtered")); + return; + } + _cservice.broadcast( _ctx.getClient(), message, new ChatService.InvocationListener() { public void requestFailed (String reason) { @@ -355,12 +350,11 @@ public class ChatDirector extends BasicDirector * of success or failure. */ public void requestTell ( - final String target, final String message, final ResultListener rl) + final String target, String msg, final ResultListener rl) { // make sure they can say what they want to say - _validateMessageOp.setMessage(target, message); - _validators.apply(_validateMessageOp); - if (!_validateMessageOp.isValid()) { + final String message = filter(msg, target, true); + if (message == null) { if (rl != null) { rl.requestFailed(null); } @@ -468,12 +462,13 @@ public class ChatDirector extends BasicDirector if (CHAT_NOTIFICATION.equals(event.getName())) { ChatMessage msg = (ChatMessage) event.getArgs()[0]; String localtype = getLocalType(event.getTargetOid()); + String message = msg.message; // if the message came from a user, make sure we want to hear it if (msg instanceof UserMessage) { String speaker = ((UserMessage) msg).speaker; - if (isBlocked(speaker)) { - // ack! block that message + message = filter(message, speaker, false); + if (message == null) { return; } else if (USER_CHAT_TYPE.equals(localtype)) { @@ -483,7 +478,7 @@ public class ChatDirector extends BasicDirector } // initialize the client-specific fields of the message - msg.setClientInfo(xlate(msg.bundle, msg.message), localtype); + msg.setClientInfo(xlate(msg.bundle, message), localtype); // and send it off! dispatchMessage(msg); @@ -527,14 +522,6 @@ public class ChatDirector extends BasicDirector return (type == null) ? PLACE_CHAT_TYPE : type; } - /** - * Returns whether chat from the specified user is to be distributed. - */ - protected boolean isBlocked (String username) - { - return (_muter != null) && _muter.isMuted(username); - } - /** * Used to assign unique ids to all speak requests. */ @@ -587,42 +574,44 @@ public class ChatDirector extends BasicDirector } /** - * An operation that checks with all chat validators to determine - * whether chat messages are valid for display. + * Run a message through all the currently registered filters. */ - protected static class ValidateMessageOp implements ObserverList.ObserverOp + protected String filter (String msg, String otherUser, boolean outgoing) { - public boolean isValid () - { - return _valid; - } + _filterMessageOp.setMessage(msg, otherUser, outgoing); + _filters.apply(_filterMessageOp); + return _filterMessageOp.getMessage(); + } - public void setMessage (String message) + /** + * An operation that checks with all chat filters to properly filter + * a message prior to sending to the server or displaying. + */ + protected static class FilterMessageOp implements ObserverList.ObserverOp + { + public void setMessage (String msg, String otherUser, boolean outgoing) { - setMessage(null, message); - } - - public void setMessage (String target, String message) - { - _target = target; - _message = message; - _valid = true; + _msg = msg; + _otherUser = otherUser; + _out = outgoing; } public boolean apply (Object observer) { - if (_target == null) { - _valid = ((ChatValidator)observer).validateSpeak(_message); - } else { - _valid = ((ChatValidator)observer).validateTell( - _target, _message); + if (_msg != null) { + _msg = ((ChatFilter) observer).filter(_msg, _otherUser, _out); } - return _valid; + return true; } - protected String _target; - protected String _message; - protected boolean _valid; + public String getMessage () + { + return _msg; + } + + protected String _otherUser; + protected String _msg; + protected boolean _out; } /** @@ -666,17 +655,14 @@ public class ChatDirector extends BasicDirector protected ObserverList _displays = new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); - /** A list of registered chat validators. */ - protected ObserverList _validators = + /** A list of registered chat filters. */ + protected ObserverList _filters = new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); /** A mapping from auxiliary chat objects to the types under which * they are registered. */ protected HashIntMap _auxes = new HashIntMap(); - /** An optionally present mutelist director. */ - protected MuteDirector _muter; - /** Validator of who may be added to the chatters list. */ protected ChatterValidator _chatterValidator; @@ -690,8 +676,8 @@ public class ChatDirector extends BasicDirector /** Used by {@link #nextRequestId}. */ protected int _requestId; - /** Operation used to validate chat messages for display. */ - protected ValidateMessageOp _validateMessageOp = new ValidateMessageOp(); + /** Operation used to filter chat messages. */ + protected FilterMessageOp _filterMessageOp = new FilterMessageOp(); /** Operation used to display chat messages. */ protected DisplayMessageOp _displayMessageOp = new DisplayMessageOp(); diff --git a/src/java/com/threerings/crowd/chat/client/ChatFilter.java b/src/java/com/threerings/crowd/chat/client/ChatFilter.java new file mode 100644 index 000000000..308a7ae56 --- /dev/null +++ b/src/java/com/threerings/crowd/chat/client/ChatFilter.java @@ -0,0 +1,22 @@ +// +// $Id: ChatFilter.java,v 1.1 2003/09/15 21:11:40 ray Exp $ + +package com.threerings.crowd.chat.client; + +/** + * Filters messages chat messages to or from the server. + */ +public interface ChatFilter +{ + /** + * Filter a chat message. + * @param msg the message text to be filtered. + * @param otherUser an optional argument that represents the target or the + * speaker, depending on 'outgoing', and can be considered in filtering if + * it is provided. + * @param outgoing true if the message is going out to the server. + * + * @return the filtered message, or null to block it completely. + */ + public String filter (String msg, String otherUser, boolean outgoing); +} diff --git a/src/java/com/threerings/crowd/chat/client/ChatValidator.java b/src/java/com/threerings/crowd/chat/client/ChatValidator.java deleted file mode 100644 index fc6f70ed7..000000000 --- a/src/java/com/threerings/crowd/chat/client/ChatValidator.java +++ /dev/null @@ -1,22 +0,0 @@ -// -// $Id: ChatValidator.java,v 1.2 2003/06/03 21:41:33 ray Exp $ - -package com.threerings.crowd.chat.client; - -/** - * A chat validator validates chat messages before they are sent to the - * server. By default, each method returns true, it is assumed that - * validators will be added that override at least one of the methods. - */ -public interface ChatValidator -{ - /** - * Validate that the specified speak message may be sent. - */ - public boolean validateSpeak (String msg); - - /** - * Validate that the specified tell message may be sent. - */ - public boolean validateTell (String target, String msg); -} diff --git a/src/java/com/threerings/crowd/chat/client/MuteDirector.java b/src/java/com/threerings/crowd/chat/client/MuteDirector.java index 31632c04f..90342b42c 100644 --- a/src/java/com/threerings/crowd/chat/client/MuteDirector.java +++ b/src/java/com/threerings/crowd/chat/client/MuteDirector.java @@ -1,5 +1,5 @@ // -// $Id: MuteDirector.java,v 1.9 2003/06/04 02:50:18 ray Exp $ +// $Id: MuteDirector.java,v 1.10 2003/09/15 21:11:40 ray Exp $ package com.threerings.crowd.chat.client; @@ -20,7 +20,7 @@ import com.threerings.presents.client.Client; * TODO: This class right now is pretty much just a placeholder. */ public class MuteDirector extends BasicDirector - implements ChatValidator + implements ChatFilter { /** * An interface that can be registered with the MuteDirector to @@ -61,8 +61,7 @@ public class MuteDirector extends BasicDirector { if (_chatdir == null) { _chatdir = chatdir; - _chatdir.addChatValidator(this); - _chatdir.setMuteDirector(this); + _chatdir.addChatFilter(this); } } @@ -113,21 +112,21 @@ public class MuteDirector extends BasicDirector return (String[]) _mutelist.toArray(new String[_mutelist.size()]); } - // documentation inherited from interface ChatValidator - public boolean validateSpeak (String msg) + // documentation inherited from interface ChatFilter + public String filter (String msg, String otherUser, boolean outgoing) { - return true; // sure! - } - - // documentation inherited from interface ChatValidator - public boolean validateTell (String target, String msg) - { - if (isMuted(target)) { - _chatdir.displayFeedback(null, "m.no_tell_mute"); - return false; + // we are only concerned with filtering things going to or coming + // from muted users + if ((otherUser != null) && isMuted(otherUser)) { + // if it was outgoing, explain the dropped message, otherwise + // silently drop + if (outgoing) { + _chatdir.displayFeedback(null, "m.no_tell_mute"); + } + return null; } - return true; // let it go through.. + return msg; } /**