- 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
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user