diff --git a/src/as/com/threerings/crowd/chat/client/ChatDirector.as b/src/as/com/threerings/crowd/chat/client/ChatDirector.as index a93ad1657..bcf119b96 100644 --- a/src/as/com/threerings/crowd/chat/client/ChatDirector.as +++ b/src/as/com/threerings/crowd/chat/client/ChatDirector.as @@ -125,6 +125,22 @@ public class ChatDirector extends BasicDirector _displays.remove(display); } + /** + * Add the supplied chat snooper to hear about chat arriving from the server, pre-filtered. + */ + public function addChatSnooper (snooper :ChatSnooper) :void + { + _snoopers.add(snooper); + } + + /** + * Remove the specified snooper. + */ + public function removeChatSnooper (snooper :ChatSnooper) :void + { + _snoopers.remove(snooper); + } + /** * 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. @@ -316,7 +332,7 @@ public class ChatDirector extends BasicDirector */ public function dispatchMessage (message :ChatMessage, localType :String) :void { - message.setClientInfo(xlate(message.bundle, message.message), localType); + setClientInfo(message, localType); dispatchPreparedMessage(message); } @@ -674,13 +690,17 @@ public class ChatDirector extends BasicDirector speaker = (msg as UserSystemMessage).speaker; } + // Translate and timestamp the message. This would happen during dispatch but we + // need to do it ahead of filtering. + setClientInfo(msg, localtype); + + // inform the "snoopers" + _snoopers.apply(function (snooper :ChatSnooper) :void { + snooper.snoopChat(msg); + }); + // if there was an originating speaker, see if we want to hear it if (speaker != null) { - // We pre-translate this message here because we're about to filter it. - // And if we filter first, we could end up filtering keys. - msg.message = xlate(msg.bundle, msg.message); - msg.bundle = null; - if ((msg.message = filter(msg.message, speaker, false)) == null) { return; } @@ -933,6 +953,16 @@ public class ChatDirector extends BasicDirector obs.chattersUpdated(_chatters); } + /** + * Set the "client info" on the specified message, if not already set. + */ + protected function setClientInfo (msg :ChatMessage, localType :String) :void + { + if (msg.localtype == null) { + msg.setClientInfo(xlate(msg.bundle, msg.message), localType); + } + } + /** * Translates the specified message using the specified bundle. */ @@ -1027,6 +1057,9 @@ public class ChatDirector extends BasicDirector /** A list of registered chat filters. */ protected var _filters :ObserverList = new ObserverList(); + /** A list of registered chat snoopers. */ + protected var _snoopers :ObserverList = new ObserverList(); + /** A mapping from auxiliary chat objects to the types under which they are registered. */ protected var _auxes :HashMap = new HashMap(); diff --git a/src/as/com/threerings/crowd/chat/client/ChatSnooper.as b/src/as/com/threerings/crowd/chat/client/ChatSnooper.as new file mode 100644 index 000000000..556411a73 --- /dev/null +++ b/src/as/com/threerings/crowd/chat/client/ChatSnooper.as @@ -0,0 +1,19 @@ +// +// $Id$ + +package com.threerings.crowd.chat.client { + +import com.threerings.crowd.chat.data.ChatMessage; + +/** + * An interface for listening to chat received from the server, prior + * to it being filtered/muted/whatever. + */ +public interface ChatSnooper +{ + /** + * Handle the arrival of chat. Do not modify the chat message! That would be a filter! + */ + function snoopChat (msg :ChatMessage) :void; +} +}