- 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;
|
package com.threerings.crowd.chat.client;
|
||||||
|
|
||||||
@@ -83,17 +83,6 @@ public class ChatDirector extends BasicDirector
|
|||||||
_ctx.getLocationDirector().addLocationObserver(this);
|
_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
|
* Adds the supplied chat display to the chat display list. It will
|
||||||
* subsequently be notified of incoming chat messages as well as tell
|
* 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
|
* Adds the specified chat filter to the list of filters. All
|
||||||
* chat requests will be validated with all validators before they may
|
* chat requests and receipts will be filtered with all filters
|
||||||
* be accepted.
|
* 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.
|
* 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)
|
SpeakService speakService, String message, byte mode)
|
||||||
{
|
{
|
||||||
// make sure they can say what they want to say
|
// make sure they can say what they want to say
|
||||||
_validateMessageOp.setMessage(message);
|
message = filter(message, null, true);
|
||||||
_validators.apply(_validateMessageOp);
|
if (message == null) {
|
||||||
if (!_validateMessageOp.isValid()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +322,13 @@ public class ChatDirector extends BasicDirector
|
|||||||
*/
|
*/
|
||||||
public void requestBroadcast (String message)
|
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(
|
_cservice.broadcast(
|
||||||
_ctx.getClient(), message, new ChatService.InvocationListener() {
|
_ctx.getClient(), message, new ChatService.InvocationListener() {
|
||||||
public void requestFailed (String reason) {
|
public void requestFailed (String reason) {
|
||||||
@@ -355,12 +350,11 @@ public class ChatDirector extends BasicDirector
|
|||||||
* of success or failure.
|
* of success or failure.
|
||||||
*/
|
*/
|
||||||
public void requestTell (
|
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
|
// make sure they can say what they want to say
|
||||||
_validateMessageOp.setMessage(target, message);
|
final String message = filter(msg, target, true);
|
||||||
_validators.apply(_validateMessageOp);
|
if (message == null) {
|
||||||
if (!_validateMessageOp.isValid()) {
|
|
||||||
if (rl != null) {
|
if (rl != null) {
|
||||||
rl.requestFailed(null);
|
rl.requestFailed(null);
|
||||||
}
|
}
|
||||||
@@ -468,12 +462,13 @@ public class ChatDirector extends BasicDirector
|
|||||||
if (CHAT_NOTIFICATION.equals(event.getName())) {
|
if (CHAT_NOTIFICATION.equals(event.getName())) {
|
||||||
ChatMessage msg = (ChatMessage) event.getArgs()[0];
|
ChatMessage msg = (ChatMessage) event.getArgs()[0];
|
||||||
String localtype = getLocalType(event.getTargetOid());
|
String localtype = getLocalType(event.getTargetOid());
|
||||||
|
String message = msg.message;
|
||||||
|
|
||||||
// if the message came from a user, make sure we want to hear it
|
// if the message came from a user, make sure we want to hear it
|
||||||
if (msg instanceof UserMessage) {
|
if (msg instanceof UserMessage) {
|
||||||
String speaker = ((UserMessage) msg).speaker;
|
String speaker = ((UserMessage) msg).speaker;
|
||||||
if (isBlocked(speaker)) {
|
message = filter(message, speaker, false);
|
||||||
// ack! block that message
|
if (message == null) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (USER_CHAT_TYPE.equals(localtype)) {
|
} else if (USER_CHAT_TYPE.equals(localtype)) {
|
||||||
@@ -483,7 +478,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initialize the client-specific fields of the message
|
// 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!
|
// and send it off!
|
||||||
dispatchMessage(msg);
|
dispatchMessage(msg);
|
||||||
@@ -527,14 +522,6 @@ public class ChatDirector extends BasicDirector
|
|||||||
return (type == null) ? PLACE_CHAT_TYPE : type;
|
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.
|
* 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
|
* Run a message through all the currently registered filters.
|
||||||
* whether chat messages are valid for display.
|
|
||||||
*/
|
*/
|
||||||
protected static class ValidateMessageOp implements ObserverList.ObserverOp
|
protected String filter (String msg, String otherUser, boolean outgoing)
|
||||||
{
|
{
|
||||||
public boolean isValid ()
|
_filterMessageOp.setMessage(msg, otherUser, outgoing);
|
||||||
{
|
_filters.apply(_filterMessageOp);
|
||||||
return _valid;
|
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);
|
_msg = msg;
|
||||||
}
|
_otherUser = otherUser;
|
||||||
|
_out = outgoing;
|
||||||
public void setMessage (String target, String message)
|
|
||||||
{
|
|
||||||
_target = target;
|
|
||||||
_message = message;
|
|
||||||
_valid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean apply (Object observer)
|
public boolean apply (Object observer)
|
||||||
{
|
{
|
||||||
if (_target == null) {
|
if (_msg != null) {
|
||||||
_valid = ((ChatValidator)observer).validateSpeak(_message);
|
_msg = ((ChatFilter) observer).filter(_msg, _otherUser, _out);
|
||||||
} else {
|
|
||||||
_valid = ((ChatValidator)observer).validateTell(
|
|
||||||
_target, _message);
|
|
||||||
}
|
}
|
||||||
return _valid;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String _target;
|
public String getMessage ()
|
||||||
protected String _message;
|
{
|
||||||
protected boolean _valid;
|
return _msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String _otherUser;
|
||||||
|
protected String _msg;
|
||||||
|
protected boolean _out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -666,17 +655,14 @@ public class ChatDirector extends BasicDirector
|
|||||||
protected ObserverList _displays =
|
protected ObserverList _displays =
|
||||||
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
|
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
|
||||||
|
|
||||||
/** A list of registered chat validators. */
|
/** A list of registered chat filters. */
|
||||||
protected ObserverList _validators =
|
protected ObserverList _filters =
|
||||||
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
|
new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
|
||||||
|
|
||||||
/** A mapping from auxiliary chat objects to the types under which
|
/** A mapping from auxiliary chat objects to the types under which
|
||||||
* they are registered. */
|
* they are registered. */
|
||||||
protected HashIntMap _auxes = new HashIntMap();
|
protected HashIntMap _auxes = new HashIntMap();
|
||||||
|
|
||||||
/** An optionally present mutelist director. */
|
|
||||||
protected MuteDirector _muter;
|
|
||||||
|
|
||||||
/** Validator of who may be added to the chatters list. */
|
/** Validator of who may be added to the chatters list. */
|
||||||
protected ChatterValidator _chatterValidator;
|
protected ChatterValidator _chatterValidator;
|
||||||
|
|
||||||
@@ -690,8 +676,8 @@ public class ChatDirector extends BasicDirector
|
|||||||
/** Used by {@link #nextRequestId}. */
|
/** Used by {@link #nextRequestId}. */
|
||||||
protected int _requestId;
|
protected int _requestId;
|
||||||
|
|
||||||
/** Operation used to validate chat messages for display. */
|
/** Operation used to filter chat messages. */
|
||||||
protected ValidateMessageOp _validateMessageOp = new ValidateMessageOp();
|
protected FilterMessageOp _filterMessageOp = new FilterMessageOp();
|
||||||
|
|
||||||
/** Operation used to display chat messages. */
|
/** Operation used to display chat messages. */
|
||||||
protected DisplayMessageOp _displayMessageOp = new DisplayMessageOp();
|
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;
|
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.
|
* TODO: This class right now is pretty much just a placeholder.
|
||||||
*/
|
*/
|
||||||
public class MuteDirector extends BasicDirector
|
public class MuteDirector extends BasicDirector
|
||||||
implements ChatValidator
|
implements ChatFilter
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* An interface that can be registered with the MuteDirector to
|
* An interface that can be registered with the MuteDirector to
|
||||||
@@ -61,8 +61,7 @@ public class MuteDirector extends BasicDirector
|
|||||||
{
|
{
|
||||||
if (_chatdir == null) {
|
if (_chatdir == null) {
|
||||||
_chatdir = chatdir;
|
_chatdir = chatdir;
|
||||||
_chatdir.addChatValidator(this);
|
_chatdir.addChatFilter(this);
|
||||||
_chatdir.setMuteDirector(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,21 +112,21 @@ public class MuteDirector extends BasicDirector
|
|||||||
return (String[]) _mutelist.toArray(new String[_mutelist.size()]);
|
return (String[]) _mutelist.toArray(new String[_mutelist.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface ChatValidator
|
// documentation inherited from interface ChatFilter
|
||||||
public boolean validateSpeak (String msg)
|
public String filter (String msg, String otherUser, boolean outgoing)
|
||||||
{
|
{
|
||||||
return true; // sure!
|
// we are only concerned with filtering things going to or coming
|
||||||
}
|
// from muted users
|
||||||
|
if ((otherUser != null) && isMuted(otherUser)) {
|
||||||
// documentation inherited from interface ChatValidator
|
// if it was outgoing, explain the dropped message, otherwise
|
||||||
public boolean validateTell (String target, String msg)
|
// silently drop
|
||||||
{
|
if (outgoing) {
|
||||||
if (isMuted(target)) {
|
_chatdir.displayFeedback(null, "m.no_tell_mute");
|
||||||
_chatdir.displayFeedback(null, "m.no_tell_mute");
|
}
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true; // let it go through..
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user