Split SpeakProvider into SpeakHandler and SpeakUtil. SpeakProvider is now a
proper interface like all the other new invocation service backends. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4795 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -67,18 +67,23 @@
|
|||||||
<exclude name="**/InvocationService.java"/>
|
<exclude name="**/InvocationService.java"/>
|
||||||
</javac>
|
</javac>
|
||||||
<!-- now generate the associated files -->
|
<!-- now generate the associated files -->
|
||||||
<service header="lib/SOURCE_HEADER" asroot="src/as"
|
<service header="lib/SOURCE_HEADER" asroot="src/as" classpathref="classpath">
|
||||||
classpathref="classpath">
|
<fileset dir="src/java" includes="**/*Service.java">
|
||||||
<fileset dir="src/java" includes="**/*Service.java"
|
<exclude name="**/InvocationService.java"/>
|
||||||
excludes="**/InvocationService.java"/>
|
<exclude name="**/peer/**"/>
|
||||||
<providerless service="AdminService"/>
|
<exclude name="**/admin/**"/>
|
||||||
|
</fileset>
|
||||||
<providerless service="ChatService"/>
|
<providerless service="ChatService"/>
|
||||||
<providerless service="SpeakService"/>
|
|
||||||
<providerless service="LocationService"/>
|
<providerless service="LocationService"/>
|
||||||
<providerless service="BodyService"/>
|
<providerless service="BodyService"/>
|
||||||
<providerless service="SimulatorService"/>
|
<providerless service="SimulatorService"/>
|
||||||
<providerless service="TimeBaseService"/>
|
<providerless service="TimeBaseService"/>
|
||||||
</service>
|
</service>
|
||||||
|
<service header="lib/SOURCE_HEADER" classpathref="classpath">
|
||||||
|
<fileset dir="src/java" includes="**/peer/**/*Service.java"/>
|
||||||
|
<fileset dir="src/java" includes="**/admin/**/*Service.java"/>
|
||||||
|
<providerless service="AdminService"/>
|
||||||
|
</service>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- generates sender and decoder classes for all invocation -->
|
<!-- generates sender and decoder classes for all invocation -->
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ import com.threerings.crowd.chat.data.ChatCodes;
|
|||||||
import com.threerings.crowd.chat.data.UserMessage;
|
import com.threerings.crowd.chat.data.UserMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The chat provider handles the server side of the chat-related
|
* The chat provider handles the server side of the chat-related invocation services.
|
||||||
* invocation services.
|
|
||||||
*/
|
*/
|
||||||
public class ChatProvider
|
public class ChatProvider
|
||||||
implements ChatCodes, InvocationProvider
|
implements ChatCodes, InvocationProvider
|
||||||
@@ -239,10 +238,10 @@ public class ChatProvider
|
|||||||
*/
|
*/
|
||||||
public void deliverTell (BodyObject target, UserMessage message)
|
public void deliverTell (BodyObject target, UserMessage message)
|
||||||
{
|
{
|
||||||
SpeakProvider.sendMessage(target, message);
|
SpeakUtil.sendMessage(target, message);
|
||||||
|
|
||||||
// note that the teller "heard" what they said
|
// note that the teller "heard" what they said
|
||||||
SpeakProvider.noteMessage(message.speaker, message);
|
SpeakUtil.noteMessage(message.speaker, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -261,13 +260,13 @@ public class ChatProvider
|
|||||||
{
|
{
|
||||||
if (from == null) {
|
if (from == null) {
|
||||||
if (attention) {
|
if (attention) {
|
||||||
SpeakProvider.sendAttention(object, bundle, msg);
|
SpeakUtil.sendAttention(object, bundle, msg);
|
||||||
} else {
|
} else {
|
||||||
SpeakProvider.sendInfo(object, bundle, msg);
|
SpeakUtil.sendInfo(object, bundle, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SpeakProvider.sendSpeak(object, from, bundle, msg, BROADCAST_MODE);
|
SpeakUtil.sendSpeak(object, from, bundle, msg, BROADCAST_MODE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
// Narya library - tools for developing networked games
|
||||||
|
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
||||||
|
// http://www.threerings.net/code/narya/
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Lesser General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
package com.threerings.crowd.chat.server;
|
||||||
|
|
||||||
|
import com.threerings.util.MessageManager;
|
||||||
|
|
||||||
|
import com.threerings.presents.data.ClientObject;
|
||||||
|
import com.threerings.presents.dobj.DObject;
|
||||||
|
import com.threerings.presents.server.InvocationManager;
|
||||||
|
|
||||||
|
import com.threerings.crowd.Log;
|
||||||
|
import com.threerings.crowd.chat.data.ChatCodes;
|
||||||
|
import com.threerings.crowd.data.BodyObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wires up the {@link SpeakService} to a particular distributed object. A server entity can make
|
||||||
|
* "speech" available among the subscribers of a particular distributed object by constructing a
|
||||||
|
* speak handler and registering it with the {@link InvocationManager}, then placing the resulting
|
||||||
|
* marshaller into the distributed object in question so that subscribers to that object can use it
|
||||||
|
* to generate "speak" requests on that object.
|
||||||
|
*/
|
||||||
|
public class SpeakHandler
|
||||||
|
implements SpeakProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Used to prevent abitrary users from issuing speak requests.
|
||||||
|
*/
|
||||||
|
public static interface SpeakerValidator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Should return true if the supplied speaker is allowed to speak
|
||||||
|
* via the speak provider with which this validator was
|
||||||
|
* registered.
|
||||||
|
*/
|
||||||
|
public boolean isValidSpeaker (DObject speakObj, ClientObject speaker, byte mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a handler that will provide speech on the supplied distributed object.
|
||||||
|
*
|
||||||
|
* @param speakObj the object for which speech requests will be processed.
|
||||||
|
* @param validator an optional validator that can be used to prevent arbitrary users from
|
||||||
|
* using the speech services on this object.
|
||||||
|
*/
|
||||||
|
public SpeakHandler (DObject speakObj, SpeakerValidator validator)
|
||||||
|
{
|
||||||
|
_speakObj = speakObj;
|
||||||
|
_validator = validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from interface SpeakProvider
|
||||||
|
public void speak (ClientObject caller, String message, byte mode)
|
||||||
|
{
|
||||||
|
// ensure that the caller has normal chat privileges
|
||||||
|
BodyObject source = (BodyObject)caller;
|
||||||
|
String errmsg = source.checkAccess(ChatCodes.CHAT_ACCESS, null);
|
||||||
|
if (errmsg != null) {
|
||||||
|
// we normally don't listen for responses to speak messages so we can't just throw an
|
||||||
|
// InvocationException we have to specifically communicate the error to the user
|
||||||
|
SpeakUtil.sendFeedback(source, MessageManager.GLOBAL_BUNDLE, errmsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: broadcast should be handled more like a system message rather than as a mode for a
|
||||||
|
// user message so that we don't have to do this validation here. Or not.
|
||||||
|
|
||||||
|
// ensure that the speaker is valid
|
||||||
|
if ((mode == ChatCodes.BROADCAST_MODE) ||
|
||||||
|
(_validator != null && !_validator.isValidSpeaker(_speakObj, caller, mode))) {
|
||||||
|
Log.warning("Refusing invalid speak request [caller=" + caller.who() +
|
||||||
|
", speakObj=" + _speakObj.which() +
|
||||||
|
", message=" + message + ", mode=" + mode + "].");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// issue the speak message on our speak object
|
||||||
|
SpeakUtil.sendSpeak(_speakObj, source.getVisibleName(), null, message, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Our speech object. */
|
||||||
|
protected DObject _speakObj;
|
||||||
|
|
||||||
|
/** The entity that will validate our speakers. */
|
||||||
|
protected SpeakerValidator _validator;
|
||||||
|
}
|
||||||
@@ -21,417 +21,19 @@
|
|||||||
|
|
||||||
package com.threerings.crowd.chat.server;
|
package com.threerings.crowd.chat.server;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.threerings.crowd.chat.client.SpeakService;
|
||||||
import java.util.HashMap;
|
import com.threerings.presents.client.Client;
|
||||||
|
|
||||||
import com.samskivert.util.ObserverList;
|
|
||||||
import com.threerings.util.MessageManager;
|
|
||||||
import com.threerings.util.Name;
|
|
||||||
|
|
||||||
import com.threerings.presents.data.ClientObject;
|
import com.threerings.presents.data.ClientObject;
|
||||||
import com.threerings.presents.dobj.DObject;
|
import com.threerings.presents.server.InvocationException;
|
||||||
import com.threerings.presents.server.InvocationProvider;
|
import com.threerings.presents.server.InvocationProvider;
|
||||||
|
|
||||||
import com.threerings.crowd.Log;
|
|
||||||
import com.threerings.crowd.data.BodyObject;
|
|
||||||
import com.threerings.crowd.server.CrowdServer;
|
|
||||||
|
|
||||||
import com.threerings.crowd.chat.client.SpeakService;
|
|
||||||
import com.threerings.crowd.chat.data.ChatCodes;
|
|
||||||
import com.threerings.crowd.chat.data.ChatMessage;
|
|
||||||
import com.threerings.crowd.chat.data.SpeakObject;
|
|
||||||
import com.threerings.crowd.chat.data.SystemMessage;
|
|
||||||
import com.threerings.crowd.chat.data.UserMessage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the back-end of the chat speaking facilities. A server entity
|
* Defines the server-side of the {@link SpeakService}.
|
||||||
* can make "speech" available among the subscribers of a particular
|
|
||||||
* distributed object by constructing a speak provider and registering it
|
|
||||||
* with the invocation manager, then placing the resulting marshaller into
|
|
||||||
* the distributed object in question so that subscribers to that object
|
|
||||||
* can use it to generate "speak" requests on that object.
|
|
||||||
*/
|
*/
|
||||||
public class SpeakProvider
|
public interface SpeakProvider extends InvocationProvider
|
||||||
implements InvocationProvider, ChatCodes
|
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Used to prevent abitrary users from issuing speak requests.
|
|
||||||
*/
|
|
||||||
public static interface SpeakerValidator
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Should return true if the supplied speaker is allowed to speak
|
|
||||||
* via the speak provider with which this validator was
|
|
||||||
* registered.
|
|
||||||
*/
|
|
||||||
public boolean isValidSpeaker (DObject speakObj, ClientObject speaker, byte mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface used to notify external systems whenever a chat
|
|
||||||
* message is spoken by one user and heard by another.
|
|
||||||
*/
|
|
||||||
public static interface MessageObserver
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Called for each player that hears a particular chat message.
|
|
||||||
*/
|
|
||||||
public void messageDelivered (Name hearer, UserMessage message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a speak provider that will provide speech on the supplied
|
|
||||||
* distributed object.
|
|
||||||
*
|
|
||||||
* @param speakObj the object for which speech requests will be
|
|
||||||
* processed.
|
|
||||||
* @param validator an optional validator that can be used to prevent
|
|
||||||
* arbitrary users from using the speech services on this object.
|
|
||||||
*/
|
|
||||||
public SpeakProvider (DObject speakObj, SpeakerValidator validator)
|
|
||||||
{
|
|
||||||
_speakObj = speakObj;
|
|
||||||
_validator = validator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a {@link MessageObserver} to be notified whenever a
|
|
||||||
* user-originated chat message is heard by another user.
|
|
||||||
*/
|
|
||||||
public static void registerMessageObserver (MessageObserver obs)
|
|
||||||
{
|
|
||||||
_messageObs.add(obs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a registration made previously with {@link
|
|
||||||
* #registerMessageObserver}.
|
|
||||||
*/
|
|
||||||
public static void removeMessageObserver (MessageObserver obs)
|
|
||||||
{
|
|
||||||
_messageObs.remove(obs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a {@link SpeakService#speak} request.
|
* Handles a {@link SpeakService#speak} request.
|
||||||
*/
|
*/
|
||||||
public void speak (ClientObject caller, String message, byte mode)
|
public void speak (ClientObject caller, String arg1, byte arg2);
|
||||||
{
|
|
||||||
// ensure that the caller has normal chat privileges
|
|
||||||
BodyObject source = (BodyObject)caller;
|
|
||||||
String errmsg = source.checkAccess(CHAT_ACCESS, null);
|
|
||||||
if (errmsg != null) {
|
|
||||||
// we normally don't listen for responses to speak messages so
|
|
||||||
// we can't just throw an InvocationException we have to
|
|
||||||
// specifically communicate the error to the user
|
|
||||||
sendFeedback(source, MessageManager.GLOBAL_BUNDLE, errmsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that the speaker is valid
|
|
||||||
// TODO: broadcast should be handled more like a system message
|
|
||||||
// rather than as a mode for a user message so that we don't
|
|
||||||
// have to do this validation here. Or not.
|
|
||||||
if ((mode == BROADCAST_MODE) ||
|
|
||||||
(_validator != null &&
|
|
||||||
!_validator.isValidSpeaker(_speakObj, caller, mode))) {
|
|
||||||
Log.warning("Refusing invalid speak request " +
|
|
||||||
"[caller=" + caller.who() +
|
|
||||||
", speakObj=" + _speakObj.which() +
|
|
||||||
", message=" + message + ", mode=" + mode + "].");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// issue the speak message on our speak object
|
|
||||||
sendSpeak(_speakObj, source.getVisibleName(), null, message, mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a speak notification to the specified place object
|
|
||||||
* originating with the specified speaker (the speaker optionally
|
|
||||||
* being a server entity that wishes to fake a "speak" message) and
|
|
||||||
* with the supplied message content.
|
|
||||||
*
|
|
||||||
* @param speakObj the object on which to generate the speak message.
|
|
||||||
* @param speaker the username of the user that generated the message
|
|
||||||
* (or some special speaker name for server messages).
|
|
||||||
* @param bundle null when the message originates from a real human,
|
|
||||||
* the bundle identifier that will be used by the client to translate
|
|
||||||
* the message text when the message originates from a server entity
|
|
||||||
* "faking" a chat message.
|
|
||||||
* @param message the text of the speak message.
|
|
||||||
*/
|
|
||||||
public static void sendSpeak (DObject speakObj, Name speaker,
|
|
||||||
String bundle, String message)
|
|
||||||
{
|
|
||||||
sendSpeak(speakObj, speaker, bundle, message, ChatCodes.DEFAULT_MODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a speak notification to the specified place object
|
|
||||||
* originating with the specified speaker (the speaker optionally
|
|
||||||
* being a server entity that wishes to fake a "speak" message) and
|
|
||||||
* with the supplied message content.
|
|
||||||
*
|
|
||||||
* @param speakObj the object on which to generate the speak message.
|
|
||||||
* @param speaker the username of the user that generated the message
|
|
||||||
* (or some special speaker name for server messages).
|
|
||||||
* @param bundle null when the message originates from a real human,
|
|
||||||
* the bundle identifier that will be used by the client to translate
|
|
||||||
* the message text when the message originates from a server entity
|
|
||||||
* "faking" a chat message.
|
|
||||||
* @param message the text of the speak message.
|
|
||||||
* @param mode the mode of the message, see {@link
|
|
||||||
* ChatCodes#DEFAULT_MODE}.
|
|
||||||
*/
|
|
||||||
public static void sendSpeak (DObject speakObj, Name speaker,
|
|
||||||
String bundle, String message, byte mode)
|
|
||||||
{
|
|
||||||
sendMessage(speakObj, new UserMessage(speaker, bundle, message, mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a system INFO message notification to the specified object with
|
|
||||||
* the supplied message content. A system message is one that will be
|
|
||||||
* rendered where the speak messages are rendered, but in a way that
|
|
||||||
* makes it clear that it is a message from the server.
|
|
||||||
*
|
|
||||||
* Info messages are sent when something happens that was neither
|
|
||||||
* directly triggered by the user, nor requires direct action.
|
|
||||||
*
|
|
||||||
* @param speakObj the object on which to deliver the message.
|
|
||||||
* @param bundle the name of the localization bundle that should be
|
|
||||||
* used to translate this system message prior to displaying it to the
|
|
||||||
* client.
|
|
||||||
* @param message the text of the message.
|
|
||||||
*/
|
|
||||||
public static void sendInfo (DObject speakObj, String bundle, String message)
|
|
||||||
{
|
|
||||||
sendSystem(speakObj, bundle, message, SystemMessage.INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a system FEEDBACK message notification to the specified
|
|
||||||
* object with the supplied message content. A system message is one
|
|
||||||
* that will be rendered where the speak messages are rendered,
|
|
||||||
* but in a way that makes it clear that it is a message from the server.
|
|
||||||
*
|
|
||||||
* Feedback messages are sent in direct response to a user action,
|
|
||||||
* usually to indicate success or failure of the user's action.
|
|
||||||
*
|
|
||||||
* @param speakObj the object on which to deliver the message.
|
|
||||||
* @param bundle the name of the localization bundle that should be
|
|
||||||
* used to translate this system message prior to displaying it to the
|
|
||||||
* client.
|
|
||||||
* @param message the text of the message.
|
|
||||||
*/
|
|
||||||
public static void sendFeedback (DObject speakObj, String bundle, String message)
|
|
||||||
{
|
|
||||||
sendSystem(speakObj, bundle, message, SystemMessage.FEEDBACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a system ATTENTION message notification to the specified
|
|
||||||
* object with the supplied message content. A system message is one
|
|
||||||
* that will be rendered where the speak messages are rendered,
|
|
||||||
* but in a way that makes it clear that it is a message from the server.
|
|
||||||
*
|
|
||||||
* Attention messages are sent when something requires user action
|
|
||||||
* that did not result from direct action by the user.
|
|
||||||
*
|
|
||||||
* @param speakObj the object on which to deliver the message.
|
|
||||||
* @param bundle the name of the localization bundle that should be
|
|
||||||
* used to translate this system message prior to displaying it to the
|
|
||||||
* client.
|
|
||||||
* @param message the text of the message.
|
|
||||||
*/
|
|
||||||
public static void sendAttention (DObject speakObj, String bundle, String message)
|
|
||||||
{
|
|
||||||
sendSystem(speakObj, bundle, message, SystemMessage.ATTENTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the specified system message on the specified dobj.
|
|
||||||
*/
|
|
||||||
protected static void sendSystem (
|
|
||||||
DObject speakObj, String bundle, String message, byte attLevel)
|
|
||||||
{
|
|
||||||
sendMessage(speakObj, new SystemMessage(message, bundle, attLevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the specified message on the specified object.
|
|
||||||
*/
|
|
||||||
public static void sendMessage (DObject speakObj, ChatMessage msg)
|
|
||||||
{
|
|
||||||
if (speakObj == null) {
|
|
||||||
Log.warning("Dropping speak message, no speak obj '" + msg + "'.");
|
|
||||||
Thread.dumpStack();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// post the message to the relevant object
|
|
||||||
speakObj.postMessage(CHAT_NOTIFICATION, new Object[] { msg });
|
|
||||||
|
|
||||||
// if this is a user message; add it to the heard history of all users that can "hear" it
|
|
||||||
if (!(msg instanceof UserMessage)) {
|
|
||||||
return;
|
|
||||||
} else if (speakObj instanceof SpeakObject) {
|
|
||||||
_messageMapper.message = (UserMessage)msg;
|
|
||||||
((SpeakObject)speakObj).applyToListeners(_messageMapper);
|
|
||||||
_messageMapper.message = null;
|
|
||||||
} else {
|
|
||||||
Log.info("Unable to note listeners [dclass=" + speakObj.getClass() +
|
|
||||||
", msg=" + msg + "].");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of {@link ChatMessage} objects to which this user
|
|
||||||
* has been privy in the recent past.
|
|
||||||
*/
|
|
||||||
public static ArrayList<ChatMessage> getChatHistory (Name username)
|
|
||||||
{
|
|
||||||
ArrayList<ChatMessage> history = getHistoryList(username);
|
|
||||||
pruneHistory(System.currentTimeMillis(), history);
|
|
||||||
return history;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to clear the chat history for the specified user.
|
|
||||||
*/
|
|
||||||
public static void clearHistory (Name username)
|
|
||||||
{
|
|
||||||
// Log.info("Clearing history for " + username + ".");
|
|
||||||
_histories.remove(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notes that the specified user was privy to the specified message. If
|
|
||||||
* {@link ChatMessage#timestamp} is not already filled in, it will be.
|
|
||||||
*/
|
|
||||||
protected static void noteMessage (Name username, UserMessage msg)
|
|
||||||
{
|
|
||||||
// fill in the message's time stamp if necessary
|
|
||||||
if (msg.timestamp == 0L) {
|
|
||||||
msg.timestamp = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
recordToChatHistory(msg, username);
|
|
||||||
// Log.info("Noted that " + username + " heard " + msg + ".");
|
|
||||||
|
|
||||||
// notify any message observers
|
|
||||||
_messageOp.init(username, msg);
|
|
||||||
_messageObs.apply(_messageOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Records the specified message to the specified users' chat histories.
|
|
||||||
* If {@link ChatMessage#timestamp} is not already filled in, it will be.
|
|
||||||
*/
|
|
||||||
public static void recordToChatHistory (UserMessage msg, Name... usernames)
|
|
||||||
{
|
|
||||||
// fill in the message's time stamp if necessary
|
|
||||||
if (msg.timestamp == 0L) {
|
|
||||||
msg.timestamp = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Name username : usernames) {
|
|
||||||
// add the message to this user's chat history
|
|
||||||
ArrayList<ChatMessage> history = getHistoryList(username);
|
|
||||||
history.add(msg);
|
|
||||||
|
|
||||||
// if the history is big enough, potentially prune it (we always
|
|
||||||
// prune when asked for the history, so this is just to balance
|
|
||||||
// memory usage with CPU expense)
|
|
||||||
if (history.size() > 15) {
|
|
||||||
pruneHistory(msg.timestamp, history);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this user's chat history, creating one if necessary.
|
|
||||||
*/
|
|
||||||
protected static ArrayList<ChatMessage> getHistoryList (Name username)
|
|
||||||
{
|
|
||||||
ArrayList<ChatMessage> history = _histories.get(username);
|
|
||||||
if (history == null) {
|
|
||||||
_histories.put(username, history = new ArrayList<ChatMessage>());
|
|
||||||
}
|
|
||||||
return history;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prunes all messages from this history which are expired.
|
|
||||||
*/
|
|
||||||
protected static void pruneHistory (long now, ArrayList<ChatMessage> history)
|
|
||||||
{
|
|
||||||
int prunepos = 0;
|
|
||||||
for (int ll = history.size(); prunepos < ll; prunepos++) {
|
|
||||||
ChatMessage msg = history.get(prunepos);
|
|
||||||
if (now - msg.timestamp < HISTORY_EXPIRATION) {
|
|
||||||
break; // stop when we get to the first valid message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
history.subList(0, prunepos).clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Used to note the recipients of a chat message. */
|
|
||||||
protected static class MessageMapper implements SpeakObject.ListenerOp
|
|
||||||
{
|
|
||||||
public UserMessage message;
|
|
||||||
|
|
||||||
public void apply (int bodyOid) {
|
|
||||||
DObject dobj = CrowdServer.omgr.getObject(bodyOid);
|
|
||||||
if (dobj != null && dobj instanceof BodyObject) {
|
|
||||||
noteMessage(((BodyObject)dobj).getVisibleName(), message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void apply (Name username) {
|
|
||||||
noteMessage(username, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Used to notify our {@link MessageObserver}s. */
|
|
||||||
protected static class MessageObserverOp
|
|
||||||
implements ObserverList.ObserverOp<MessageObserver>
|
|
||||||
{
|
|
||||||
public void init (Name hearer, UserMessage message) {
|
|
||||||
_hearer = hearer;
|
|
||||||
_message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean apply (MessageObserver observer) {
|
|
||||||
observer.messageDelivered(_hearer, _message);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Name _hearer;
|
|
||||||
protected UserMessage _message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Our speech object. */
|
|
||||||
protected DObject _speakObj;
|
|
||||||
|
|
||||||
/** The entity that will validate our speakers. */
|
|
||||||
protected SpeakerValidator _validator;
|
|
||||||
|
|
||||||
/** Recent chat history for the server. */
|
|
||||||
protected static HashMap<Name,ArrayList<ChatMessage>> _histories =
|
|
||||||
new HashMap<Name,ArrayList<ChatMessage>>();
|
|
||||||
|
|
||||||
/** Used to note the recipients of a chat message. */
|
|
||||||
protected static MessageMapper _messageMapper = new MessageMapper();
|
|
||||||
|
|
||||||
/** A list of {@link MessageObserver}s. */
|
|
||||||
protected static ObserverList<MessageObserver> _messageObs =
|
|
||||||
new ObserverList<MessageObserver>(ObserverList.FAST_UNSAFE_NOTIFY);
|
|
||||||
|
|
||||||
/** Used to notify our {@link MessageObserver}s. */
|
|
||||||
protected static MessageObserverOp _messageOp = new MessageObserverOp();
|
|
||||||
|
|
||||||
/** The amount of time before chat history becomes... history. */
|
|
||||||
protected static final long HISTORY_EXPIRATION = 5L * 60L * 1000L;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,349 @@
|
|||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
// Narya library - tools for developing networked games
|
||||||
|
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
||||||
|
// http://www.threerings.net/code/narya/
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Lesser General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
package com.threerings.crowd.chat.server;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.samskivert.util.ObserverList;
|
||||||
|
import com.threerings.util.Name;
|
||||||
|
|
||||||
|
import com.threerings.presents.data.ClientObject;
|
||||||
|
import com.threerings.presents.dobj.DObject;
|
||||||
|
import com.threerings.presents.server.InvocationProvider;
|
||||||
|
|
||||||
|
import com.threerings.crowd.Log;
|
||||||
|
import com.threerings.crowd.data.BodyObject;
|
||||||
|
import com.threerings.crowd.server.CrowdServer;
|
||||||
|
|
||||||
|
import com.threerings.crowd.chat.client.SpeakService;
|
||||||
|
import com.threerings.crowd.chat.data.ChatCodes;
|
||||||
|
import com.threerings.crowd.chat.data.ChatMessage;
|
||||||
|
import com.threerings.crowd.chat.data.SpeakObject;
|
||||||
|
import com.threerings.crowd.chat.data.SystemMessage;
|
||||||
|
import com.threerings.crowd.chat.data.UserMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the back-end of the chat speaking facilities.
|
||||||
|
*/
|
||||||
|
public class SpeakUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An interface used to notify external systems whenever a chat message is spoken by one user
|
||||||
|
* and heard by another.
|
||||||
|
*/
|
||||||
|
public static interface MessageObserver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Called for each player that hears a particular chat message.
|
||||||
|
*/
|
||||||
|
public void messageDelivered (Name hearer, UserMessage message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a {@link MessageObserver} to be notified whenever a user-originated chat message
|
||||||
|
* is heard by another user.
|
||||||
|
*/
|
||||||
|
public static void registerMessageObserver (MessageObserver obs)
|
||||||
|
{
|
||||||
|
_messageObs.add(obs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a registration made previously with {@link #registerMessageObserver}.
|
||||||
|
*/
|
||||||
|
public static void removeMessageObserver (MessageObserver obs)
|
||||||
|
{
|
||||||
|
_messageObs.remove(obs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a speak notification to the specified place object originating with the specified
|
||||||
|
* speaker (the speaker optionally being a server entity that wishes to fake a "speak" message)
|
||||||
|
* and with the supplied message content.
|
||||||
|
*
|
||||||
|
* @param speakObj the object on which to generate the speak message.
|
||||||
|
* @param speaker the username of the user that generated the message (or some special speaker
|
||||||
|
* name for server messages).
|
||||||
|
* @param bundle null when the message originates from a real human, the bundle identifier that
|
||||||
|
* will be used by the client to translate the message text when the message originates from a
|
||||||
|
* server entity "faking" a chat message.
|
||||||
|
* @param message the text of the speak message.
|
||||||
|
*/
|
||||||
|
public static void sendSpeak (DObject speakObj, Name speaker, String bundle, String message)
|
||||||
|
{
|
||||||
|
sendSpeak(speakObj, speaker, bundle, message, ChatCodes.DEFAULT_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a speak notification to the specified place object originating with the specified
|
||||||
|
* speaker (the speaker optionally being a server entity that wishes to fake a "speak" message)
|
||||||
|
* and with the supplied message content.
|
||||||
|
*
|
||||||
|
* @param speakObj the object on which to generate the speak message.
|
||||||
|
* @param speaker the username of the user that generated the message (or some special speaker
|
||||||
|
* name for server messages).
|
||||||
|
* @param bundle null when the message originates from a real human, the bundle identifier that
|
||||||
|
* will be used by the client to translate the message text when the message originates from a
|
||||||
|
* server entity "faking" a chat message.
|
||||||
|
* @param message the text of the speak message.
|
||||||
|
* @param mode the mode of the message, see {@link ChatCodes#DEFAULT_MODE}.
|
||||||
|
*/
|
||||||
|
public static void sendSpeak (DObject speakObj, Name speaker, String bundle, String message,
|
||||||
|
byte mode)
|
||||||
|
{
|
||||||
|
sendMessage(speakObj, new UserMessage(speaker, bundle, message, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a system INFO message notification to the specified object with the supplied message
|
||||||
|
* content. A system message is one that will be rendered where the speak messages are
|
||||||
|
* rendered, but in a way that makes it clear that it is a message from the server.
|
||||||
|
*
|
||||||
|
* Info messages are sent when something happens that was neither directly triggered by the
|
||||||
|
* user, nor requires direct action.
|
||||||
|
*
|
||||||
|
* @param speakObj the object on which to deliver the message.
|
||||||
|
* @param bundle the name of the localization bundle that should be used to translate this
|
||||||
|
* system message prior to displaying it to the client.
|
||||||
|
* @param message the text of the message.
|
||||||
|
*/
|
||||||
|
public static void sendInfo (DObject speakObj, String bundle, String message)
|
||||||
|
{
|
||||||
|
sendSystem(speakObj, bundle, message, SystemMessage.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a system FEEDBACK message notification to the specified object with the supplied
|
||||||
|
* message content. A system message is one that will be rendered where the speak messages are
|
||||||
|
* rendered, but in a way that makes it clear that it is a message from the server.
|
||||||
|
*
|
||||||
|
* Feedback messages are sent in direct response to a user action, usually to indicate success
|
||||||
|
* or failure of the user's action.
|
||||||
|
*
|
||||||
|
* @param speakObj the object on which to deliver the message.
|
||||||
|
* @param bundle the name of the localization bundle that should be used to translate this
|
||||||
|
* system message prior to displaying it to the client.
|
||||||
|
* @param message the text of the message.
|
||||||
|
*/
|
||||||
|
public static void sendFeedback (DObject speakObj, String bundle, String message)
|
||||||
|
{
|
||||||
|
sendSystem(speakObj, bundle, message, SystemMessage.FEEDBACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a system ATTENTION message notification to the specified object with the supplied
|
||||||
|
* message content. A system message is one that will be rendered where the speak messages are
|
||||||
|
* rendered, but in a way that makes it clear that it is a message from the server.
|
||||||
|
*
|
||||||
|
* Attention messages are sent when something requires user action that did not result from
|
||||||
|
* direct action by the user.
|
||||||
|
*
|
||||||
|
* @param speakObj the object on which to deliver the message.
|
||||||
|
* @param bundle the name of the localization bundle that should be used to translate this
|
||||||
|
* system message prior to displaying it to the client.
|
||||||
|
* @param message the text of the message.
|
||||||
|
*/
|
||||||
|
public static void sendAttention (DObject speakObj, String bundle, String message)
|
||||||
|
{
|
||||||
|
sendSystem(speakObj, bundle, message, SystemMessage.ATTENTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the specified message on the specified object.
|
||||||
|
*/
|
||||||
|
public static void sendMessage (DObject speakObj, ChatMessage msg)
|
||||||
|
{
|
||||||
|
if (speakObj == null) {
|
||||||
|
Log.warning("Dropping speak message, no speak obj '" + msg + "'.");
|
||||||
|
Thread.dumpStack();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// post the message to the relevant object
|
||||||
|
speakObj.postMessage(ChatCodes.CHAT_NOTIFICATION, new Object[] { msg });
|
||||||
|
|
||||||
|
// if this is a user message; add it to the heard history of all users that can "hear" it
|
||||||
|
if (!(msg instanceof UserMessage)) {
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (speakObj instanceof SpeakObject) {
|
||||||
|
_messageMapper.message = (UserMessage)msg;
|
||||||
|
((SpeakObject)speakObj).applyToListeners(_messageMapper);
|
||||||
|
_messageMapper.message = null;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.info("Unable to note listeners [dclass=" + speakObj.getClass() +
|
||||||
|
", msg=" + msg + "].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of {@link ChatMessage} objects to which this user has been privy in the
|
||||||
|
* recent past.
|
||||||
|
*/
|
||||||
|
public static ArrayList<ChatMessage> getChatHistory (Name username)
|
||||||
|
{
|
||||||
|
ArrayList<ChatMessage> history = getHistoryList(username);
|
||||||
|
pruneHistory(System.currentTimeMillis(), history);
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to clear the chat history for the specified user.
|
||||||
|
*/
|
||||||
|
public static void clearHistory (Name username)
|
||||||
|
{
|
||||||
|
// Log.info("Clearing history for " + username + ".");
|
||||||
|
_histories.remove(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records the specified message to the specified users' chat histories. If {@link
|
||||||
|
* ChatMessage#timestamp} is not already filled in, it will be.
|
||||||
|
*/
|
||||||
|
public static void recordToChatHistory (UserMessage msg, Name... usernames)
|
||||||
|
{
|
||||||
|
// fill in the message's time stamp if necessary
|
||||||
|
if (msg.timestamp == 0L) {
|
||||||
|
msg.timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Name username : usernames) {
|
||||||
|
// add the message to this user's chat history
|
||||||
|
ArrayList<ChatMessage> history = getHistoryList(username);
|
||||||
|
history.add(msg);
|
||||||
|
|
||||||
|
// if the history is big enough, potentially prune it (we always prune when asked for
|
||||||
|
// the history, so this is just to balance memory usage with CPU expense)
|
||||||
|
if (history.size() > 15) {
|
||||||
|
pruneHistory(msg.timestamp, history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notes that the specified user was privy to the specified message. If {@link
|
||||||
|
* ChatMessage#timestamp} is not already filled in, it will be.
|
||||||
|
*/
|
||||||
|
protected static void noteMessage (Name username, UserMessage msg)
|
||||||
|
{
|
||||||
|
// fill in the message's time stamp if necessary
|
||||||
|
if (msg.timestamp == 0L) {
|
||||||
|
msg.timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
recordToChatHistory(msg, username);
|
||||||
|
// Log.info("Noted that " + username + " heard " + msg + ".");
|
||||||
|
|
||||||
|
// notify any message observers
|
||||||
|
_messageOp.init(username, msg);
|
||||||
|
_messageObs.apply(_messageOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the specified system message on the specified dobj.
|
||||||
|
*/
|
||||||
|
protected static void sendSystem (DObject speakObj, String bundle, String message, byte level)
|
||||||
|
{
|
||||||
|
sendMessage(speakObj, new SystemMessage(message, bundle, level));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this user's chat history, creating one if necessary.
|
||||||
|
*/
|
||||||
|
protected static ArrayList<ChatMessage> getHistoryList (Name username)
|
||||||
|
{
|
||||||
|
ArrayList<ChatMessage> history = _histories.get(username);
|
||||||
|
if (history == null) {
|
||||||
|
_histories.put(username, history = new ArrayList<ChatMessage>());
|
||||||
|
}
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prunes all messages from this history which are expired.
|
||||||
|
*/
|
||||||
|
protected static void pruneHistory (long now, ArrayList<ChatMessage> history)
|
||||||
|
{
|
||||||
|
int prunepos = 0;
|
||||||
|
for (int ll = history.size(); prunepos < ll; prunepos++) {
|
||||||
|
ChatMessage msg = history.get(prunepos);
|
||||||
|
if (now - msg.timestamp < HISTORY_EXPIRATION) {
|
||||||
|
break; // stop when we get to the first valid message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
history.subList(0, prunepos).clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Used to note the recipients of a chat message. */
|
||||||
|
protected static class MessageMapper implements SpeakObject.ListenerOp
|
||||||
|
{
|
||||||
|
public UserMessage message;
|
||||||
|
|
||||||
|
public void apply (int bodyOid) {
|
||||||
|
DObject dobj = CrowdServer.omgr.getObject(bodyOid);
|
||||||
|
if (dobj != null && dobj instanceof BodyObject) {
|
||||||
|
noteMessage(((BodyObject)dobj).getVisibleName(), message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void apply (Name username) {
|
||||||
|
noteMessage(username, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Used to notify our {@link MessageObserver}s. */
|
||||||
|
protected static class MessageObserverOp
|
||||||
|
implements ObserverList.ObserverOp<MessageObserver>
|
||||||
|
{
|
||||||
|
public void init (Name hearer, UserMessage message) {
|
||||||
|
_hearer = hearer;
|
||||||
|
_message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply (MessageObserver observer) {
|
||||||
|
observer.messageDelivered(_hearer, _message);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Name _hearer;
|
||||||
|
protected UserMessage _message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Recent chat history for the server. */
|
||||||
|
protected static HashMap<Name,ArrayList<ChatMessage>> _histories =
|
||||||
|
new HashMap<Name,ArrayList<ChatMessage>>();
|
||||||
|
|
||||||
|
/** Used to note the recipients of a chat message. */
|
||||||
|
protected static MessageMapper _messageMapper = new MessageMapper();
|
||||||
|
|
||||||
|
/** A list of {@link MessageObserver}s. */
|
||||||
|
protected static ObserverList<MessageObserver> _messageObs =
|
||||||
|
new ObserverList<MessageObserver>(ObserverList.FAST_UNSAFE_NOTIFY);
|
||||||
|
|
||||||
|
/** Used to notify our {@link MessageObserver}s. */
|
||||||
|
protected static MessageObserverOp _messageOp = new MessageObserverOp();
|
||||||
|
|
||||||
|
/** The amount of time before chat history becomes... history. */
|
||||||
|
protected static final long HISTORY_EXPIRATION = 5L * 60L * 1000L;
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ import com.threerings.presents.dobj.AccessController;
|
|||||||
import com.threerings.presents.server.PresentsClient;
|
import com.threerings.presents.server.PresentsClient;
|
||||||
|
|
||||||
import com.threerings.crowd.Log;
|
import com.threerings.crowd.Log;
|
||||||
import com.threerings.crowd.chat.server.SpeakProvider;
|
import com.threerings.crowd.chat.server.SpeakUtil;
|
||||||
import com.threerings.crowd.data.BodyObject;
|
import com.threerings.crowd.data.BodyObject;
|
||||||
import com.threerings.crowd.data.OccupantInfo;
|
import com.threerings.crowd.data.OccupantInfo;
|
||||||
import com.threerings.crowd.server.CrowdServer;
|
import com.threerings.crowd.server.CrowdServer;
|
||||||
@@ -78,7 +78,7 @@ public class CrowdClient extends PresentsClient
|
|||||||
|
|
||||||
// clear our chat history
|
// clear our chat history
|
||||||
if (body != null) {
|
if (body != null) {
|
||||||
SpeakProvider.clearHistory(body.getVisibleName());
|
SpeakUtil.clearHistory(body.getVisibleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ import com.threerings.crowd.data.PlaceObject;
|
|||||||
|
|
||||||
import com.threerings.crowd.chat.data.SpeakMarshaller;
|
import com.threerings.crowd.chat.data.SpeakMarshaller;
|
||||||
import com.threerings.crowd.chat.server.SpeakDispatcher;
|
import com.threerings.crowd.chat.server.SpeakDispatcher;
|
||||||
import com.threerings.crowd.chat.server.SpeakProvider;
|
import com.threerings.crowd.chat.server.SpeakHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The place manager is the server-side entity that handles all place-related interaction. It
|
* The place manager is the server-side entity that handles all place-related interaction. It
|
||||||
@@ -76,7 +76,7 @@ import com.threerings.crowd.chat.server.SpeakProvider;
|
|||||||
* well as through event listeners.
|
* well as through event listeners.
|
||||||
*/
|
*/
|
||||||
public class PlaceManager
|
public class PlaceManager
|
||||||
implements MessageListener, OidListListener, ObjectDeathListener, SpeakProvider.SpeakerValidator
|
implements MessageListener, OidListListener, ObjectDeathListener, SpeakHandler.SpeakerValidator
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* An interface used to allow the registration of standard message handlers to be invoked by
|
* An interface used to allow the registration of standard message handlers to be invoked by
|
||||||
@@ -231,7 +231,7 @@ public class PlaceManager
|
|||||||
// to speak in this place
|
// to speak in this place
|
||||||
if (shouldCreateSpeakService()) {
|
if (shouldCreateSpeakService()) {
|
||||||
plobj.setSpeakService((SpeakMarshaller)_invmgr.registerDispatcher(
|
plobj.setSpeakService((SpeakMarshaller)_invmgr.registerDispatcher(
|
||||||
new SpeakDispatcher(new SpeakProvider(plobj, this))));
|
new SpeakDispatcher(new SpeakHandler(plobj, this))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// we'll need to hear about place object events
|
// we'll need to hear about place object events
|
||||||
|
|||||||
Reference in New Issue
Block a user