The great invocation services rethink of 2002! Rearchitected the remote
method invocation services and converted everything to the new style. Could this be my biggest checkin ever? git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1642 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
//
|
||||
// $Id: ChatMessageHandler.java,v 1.6 2002/04/30 17:27:30 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.presents.dobj.MessageEvent;
|
||||
|
||||
import com.threerings.crowd.Log;
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.server.CrowdServer;
|
||||
import com.threerings.crowd.server.PlaceManager;
|
||||
|
||||
/**
|
||||
* The chat message handler handles chat messages that are issued on a
|
||||
* place object with the intention of speaking to everyone in that place.
|
||||
*/
|
||||
public class ChatMessageHandler implements PlaceManager.MessageHandler
|
||||
{
|
||||
/**
|
||||
* Handles {@link ChatCodes#SPEAK_REQUEST} messages.
|
||||
*/
|
||||
public void handleEvent (MessageEvent event, PlaceManager pmgr)
|
||||
{
|
||||
// presently we do no ratification of chat messages, so we just
|
||||
// generate a chat notification with the message and name of the
|
||||
// speaker
|
||||
int soid = event.getSourceOid();
|
||||
BodyObject source = (BodyObject)CrowdServer.omgr.getObject(soid);
|
||||
if (source == null) {
|
||||
Log.info("Chatter went away. Dropping chat request " +
|
||||
"[req=" + event + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// parse our incoming arguments
|
||||
Object[] inargs = event.getArgs();
|
||||
int reqid = ((Integer)inargs[0]).intValue();
|
||||
String message = (String)inargs[1];
|
||||
|
||||
// and generate a chat notification
|
||||
ChatProvider.sendChatMessage(
|
||||
event.getTargetOid(), source.username, null, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id: ChatDecoder.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.crowd.chat.ChatReceiver;
|
||||
import com.threerings.presents.client.InvocationDecoder;
|
||||
|
||||
/**
|
||||
* Dispatches calls to a {@link ChatReceiver} instance.
|
||||
*/
|
||||
public class ChatDecoder extends InvocationDecoder
|
||||
{
|
||||
/** The generated hash code used to identify this receiver class. */
|
||||
public static final String RECEIVER_CODE = "50d26fa68e407846184dc06b78db3e1d";
|
||||
|
||||
/** The method id used to dispatch {@link ChatReceiver#receivedTell}
|
||||
* notifications. */
|
||||
public static final int RECEIVED_TELL = 1;
|
||||
|
||||
/**
|
||||
* Creates a decoder that may be registered to dispatch invocation
|
||||
* service notifications to the specified receiver.
|
||||
*/
|
||||
public ChatDecoder (ChatReceiver receiver)
|
||||
{
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getReceiverCode ()
|
||||
{
|
||||
return RECEIVER_CODE;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchNotification (int methodId, Object[] args)
|
||||
{
|
||||
switch (methodId) {
|
||||
case RECEIVED_TELL:
|
||||
((ChatReceiver)receiver).receivedTell(
|
||||
(String)args[0], (String)args[1], (String)args[2]
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchNotification(methodId, args);
|
||||
}
|
||||
}
|
||||
|
||||
// Generated on 11:25:46 08/12/02.
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ChatDirector.java,v 1.32 2002/08/14 00:48:57 shaper Exp $
|
||||
// $Id: ChatDirector.java,v 1.33 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
@@ -8,7 +8,6 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.Tuple;
|
||||
|
||||
import com.threerings.presents.client.*;
|
||||
import com.threerings.presents.dobj.*;
|
||||
@@ -26,9 +25,8 @@ import com.threerings.crowd.util.CrowdContext;
|
||||
* services. It handles both place constrained chat as well as direct
|
||||
* messaging.
|
||||
*/
|
||||
public class ChatDirector
|
||||
implements LocationObserver, MessageListener, InvocationReceiver,
|
||||
ChatCodes
|
||||
public class ChatDirector extends BasicDirector
|
||||
implements ChatCodes, LocationObserver, MessageListener, ChatReceiver
|
||||
{
|
||||
/**
|
||||
* An interface that can receive information about the {@link
|
||||
@@ -50,6 +48,8 @@ public class ChatDirector
|
||||
*/
|
||||
public ChatDirector (CrowdContext ctx, MessageManager msgmgr, String bundle)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
// keep the context around
|
||||
_ctx = ctx;
|
||||
_msgmgr = msgmgr;
|
||||
@@ -57,7 +57,7 @@ public class ChatDirector
|
||||
|
||||
// register for chat notifications
|
||||
_ctx.getClient().getInvocationDirector().registerReceiver(
|
||||
MODULE_NAME, this);
|
||||
new ChatDecoder(this));
|
||||
|
||||
// register ourselves as a location observer
|
||||
_ctx.getLocationDirector().addLocationObserver(this);
|
||||
@@ -218,41 +218,55 @@ public class ChatDirector
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a speak message be generated and delivered to all
|
||||
* users that occupy the place object that we currently occupy.
|
||||
*
|
||||
* @param message the contents of the speak message.
|
||||
*
|
||||
* @return an id which can be used to coordinate this speak request
|
||||
* with the response that will be delivered to all active chat
|
||||
* displays when it arrives, or -1 if we were unable to make the
|
||||
* request because we are not currently in a place.
|
||||
* Dispatches a {@link #requestSpeak(SpeakService,String,byte)} on the
|
||||
* place object that we currently occupy.
|
||||
*/
|
||||
public int requestSpeak (String message)
|
||||
public void requestSpeak (String message)
|
||||
{
|
||||
requestSpeak(message, DEFAULT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a {@link #requestSpeak(SpeakService,String,byte)} on the
|
||||
* place object that we currently occupy.
|
||||
*/
|
||||
public void requestSpeak (String message, byte mode)
|
||||
{
|
||||
// make sure we're currently in a place
|
||||
if (_place == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// make sure they can say what they want to say
|
||||
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) {
|
||||
if (!((ChatValidator) iter.next()).validateSpeak(message)) {
|
||||
return -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// dispatch a speak request on the active place object
|
||||
int reqid =
|
||||
_ctx.getClient().getInvocationDirector().nextInvocationId();
|
||||
Object[] args = new Object[] { new Integer(reqid), message };
|
||||
MessageEvent mevt = new MessageEvent(
|
||||
_place.getOid(), SPEAK_REQUEST, args);
|
||||
_ctx.getDObjectManager().postEvent(mevt);
|
||||
// TODO: when this gets changed such that we actually validate
|
||||
// this on the server, we have to make sure that the
|
||||
// user is not on a portal before we allow the 'shout' to go through
|
||||
return reqid;
|
||||
requestSpeak(_place.speakService, message, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a speak message with the specified mode be generated
|
||||
* and delivered via the supplied speak service instance (which will
|
||||
* be associated with a particular "speak object"). The message will
|
||||
* first be validated by all registered {@link ChatValidator}s (and
|
||||
* possibly vetoed) before being dispatched.
|
||||
*
|
||||
* @param speakService the speak service to use when generating the
|
||||
* speak request.
|
||||
* @param message the contents of the speak message.
|
||||
* @param mode a speech mode that will be interpreted by the {@link
|
||||
* ChatDisplay} implementations that eventually display this speak
|
||||
* message.
|
||||
*/
|
||||
public void requestSpeak (
|
||||
SpeakService speakService, String message, byte mode)
|
||||
{
|
||||
// make sure they can say what they want to say
|
||||
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) {
|
||||
if (!((ChatValidator) iter.next()).validateSpeak(message)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch a speak request using the supplied speak service
|
||||
speakService.speak(_ctx.getClient(), message, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,26 +276,34 @@ public class ChatDirector
|
||||
* @param target the username of the user to which the tell message
|
||||
* should be delivered.
|
||||
* @param message the contents of the tell message.
|
||||
*
|
||||
* @return an id which can be used to coordinate this request with the
|
||||
* tell response that will be delivered to all active chat displays
|
||||
* when it arrives.
|
||||
*/
|
||||
public int requestTell (String target, String message)
|
||||
public void requestTell (final String target, final String message)
|
||||
{
|
||||
// make sure they can say what they want to say
|
||||
for (Iterator iter = _validators.iterator(); iter.hasNext(); ) {
|
||||
if (!((ChatValidator) iter.next()).validateTell(
|
||||
target, message)) {
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int invid = ChatService.tell(_ctx.getClient(), target, message, this);
|
||||
// cache the tell info for use when reporting success or failure
|
||||
// to our various chat displays
|
||||
_tells.put(invid, new Tuple(target, message));
|
||||
return invid;
|
||||
// create a listener that will report success or failure
|
||||
ChatService.TellListener listener = new ChatService.TellListener() {
|
||||
public void tellSucceeded () {
|
||||
String msg = MessageBundle.tcompose(
|
||||
"m.told_format", target, message);
|
||||
displayFeedbackMessage(_bundle, msg);
|
||||
addChatter(target);
|
||||
}
|
||||
|
||||
public void requestFailed (String reason) {
|
||||
String msg =
|
||||
MessageBundle.compose("m.tell_failed", target, reason);
|
||||
displayFeedbackMessage(_bundle, msg);
|
||||
}
|
||||
};
|
||||
|
||||
_cservice.tell(_ctx.getClient(), target, message, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,6 +330,13 @@ public class ChatDirector
|
||||
_auxes.remove(source.getOid());
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
protected void fetchServices (Client client)
|
||||
{
|
||||
// get a handle on our chat service
|
||||
_cservice = (ChatService)client.requireService(ChatService.class);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean locationMayChange (int placeId)
|
||||
{
|
||||
@@ -340,88 +369,33 @@ public class ChatDirector
|
||||
public void messageReceived (MessageEvent event)
|
||||
{
|
||||
String name = event.getName();
|
||||
if (name.equals(ChatService.SPEAK_NOTIFICATION)) {
|
||||
if (name.equals(SPEAK_NOTIFICATION)) {
|
||||
handleSpeakMessage(
|
||||
getLocalType(event.getTargetOid()), event.getArgs());
|
||||
|
||||
} else if (name.equals(ChatService.SYSTEM_NOTIFICATION)) {
|
||||
} else if (name.equals(SYSTEM_NOTIFICATION)) {
|
||||
handleSystemMessage(
|
||||
getLocalType(event.getTargetOid()), event.getArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the invocation director when another client has requested
|
||||
* a tell message be delivered to this client.
|
||||
*/
|
||||
public void handleTellNotification (String source, String message)
|
||||
// documentation inherited from interface
|
||||
public void receivedTell (String speaker, String bundle, String message)
|
||||
{
|
||||
// bail if the speaker is blocked
|
||||
if (isBlocked(source)) {
|
||||
// ignore messages from blocked users
|
||||
if (isBlocked(speaker)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the message need be translated, do so
|
||||
if (bundle != null) {
|
||||
message = xlate(bundle, message);
|
||||
}
|
||||
|
||||
UserMessage um = new UserMessage(
|
||||
message, ChatCodes.TELL_CHAT_TYPE, source, ChatCodes.DEFAULT_MODE);
|
||||
message, ChatCodes.TELL_CHAT_TYPE, speaker, ChatCodes.DEFAULT_MODE);
|
||||
dispatchMessage(um);
|
||||
addChatter(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the invocation director when an entity on the server has
|
||||
* requested that we deliver a tell notification to this
|
||||
* client. Because the server generated the notification, displays
|
||||
* will want to translate the message itself using the supplied bundle
|
||||
* identifier.
|
||||
*/
|
||||
public void handleTellNotification (
|
||||
String source, String bundle, String message)
|
||||
{
|
||||
handleTellNotification(source, xlate(bundle, message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a tell request that succeeded.
|
||||
*
|
||||
* @param invid the invocation id of the tell request.
|
||||
*/
|
||||
public void handleTellSucceeded (int invid)
|
||||
{
|
||||
// remove the tell info for the successful request
|
||||
Tuple tup = (Tuple)_tells.remove(invid);
|
||||
if (tup == null) {
|
||||
Log.warning("Notified of successful tell request but no " +
|
||||
"tell info available [invid=" + invid + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// pass this on to our chat displays
|
||||
String target = (String)tup.left, message = (String)tup.right;
|
||||
displayFeedbackMessage(
|
||||
_bundle, MessageBundle.tcompose("m.told_format", target, message));
|
||||
addChatter(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a tell request that failed.
|
||||
*
|
||||
* @param invid the invocation id of the tell request.
|
||||
* @param reason the code that describes the reason for failure.
|
||||
*/
|
||||
public void handleTellFailed (int invid, String reason)
|
||||
{
|
||||
// remove the tell info for the failed request
|
||||
Tuple tup = (Tuple)_tells.remove(invid);
|
||||
if (tup == null) {
|
||||
Log.warning("Notified of failed tell request but no " +
|
||||
"tell info available [invid=" + invid + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// pass this on to our chat displays
|
||||
String target = (String)tup.left;
|
||||
displayFeedbackMessage(
|
||||
_bundle, MessageBundle.compose("m.tell_failed", target, reason));
|
||||
addChatter(speaker);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,9 +493,20 @@ public class ChatDirector
|
||||
return (_muter != null) && _muter.isMuted(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to assign unique ids to all speak requests.
|
||||
*/
|
||||
protected synchronized int nextRequestId ()
|
||||
{
|
||||
return _requestId++;
|
||||
}
|
||||
|
||||
/** Our active chat context. */
|
||||
protected CrowdContext _ctx;
|
||||
|
||||
/** Provides access to chat-related server-side services. */
|
||||
protected ChatService _cservice;
|
||||
|
||||
/** The message manager. */
|
||||
protected MessageManager _msgmgr;
|
||||
|
||||
@@ -544,16 +529,15 @@ public class ChatDirector
|
||||
/** An optionally present mutelist director. */
|
||||
protected MuteDirector _muter;
|
||||
|
||||
/** A cache of the target and message text associated with outstanding
|
||||
* tell chat requests. */
|
||||
protected HashIntMap _tells = new HashIntMap();
|
||||
|
||||
/** Usernames of users we've recently chatted with. */
|
||||
protected LinkedList _chatters = new LinkedList();
|
||||
|
||||
/** Observers that are watching our chatters list. */
|
||||
protected ArrayList _chatterObservers = new ArrayList();
|
||||
|
||||
/** Used by {@link #nextRequestId}. */
|
||||
protected int _requestId;
|
||||
|
||||
/** The maximum number of chatter usernames to track. */
|
||||
protected static final int MAX_CHATTERS = 6;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// $Id: ChatReceiver.java,v 1.3 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
|
||||
/**
|
||||
* Defines, for the chat services, a set of notifications delivered
|
||||
* asynchronously by the server to the client.
|
||||
*/
|
||||
public interface ChatReceiver extends InvocationReceiver
|
||||
{
|
||||
/**
|
||||
* Called when a tell message is received from another player on the
|
||||
* server.
|
||||
*
|
||||
* @param speaker the username of the user from which this message
|
||||
* originated.
|
||||
* @param bundle if non-null, a bundle that should be used to
|
||||
* translate the text of the tell message. This is generally only used
|
||||
* when some server entity originates the tell message rather than
|
||||
* another user. The server entity might then wish for its tell
|
||||
* message to be translated into a language appropriate for the
|
||||
* receiver. Such luxuries are not available for human to human
|
||||
* conversation, alas.
|
||||
* @param message the text of the tell message.
|
||||
*/
|
||||
public void receivedTell (String speaker, String bundle, String message);
|
||||
}
|
||||
@@ -1,22 +1,31 @@
|
||||
//
|
||||
// $Id: ChatService.java,v 1.7 2002/05/15 23:54:34 mdb Exp $
|
||||
// $Id: ChatService.java,v 1.8 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationDirector;
|
||||
import com.threerings.crowd.Log;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* The chat services provide a mechanism by which the client can broadcast
|
||||
* chat messages to all clients that are subscribed to a particular place
|
||||
* object or directly to a particular client. These services should not be
|
||||
* used directly, but instead should be accessed via the chat director.
|
||||
*
|
||||
* @see ChatDirector
|
||||
* used directly, but instead should be accessed via the {@link
|
||||
* ChatDirector}.
|
||||
*/
|
||||
public class ChatService implements ChatCodes
|
||||
public interface ChatService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Used to communicate the response to a {@link #tell} request.
|
||||
*/
|
||||
public static interface TellListener extends InvocationListener
|
||||
{
|
||||
/**
|
||||
* Communicates the response to a {@link #tell} request.
|
||||
*/
|
||||
public void tellSucceeded ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a tell message be delivered to the user with username
|
||||
* equal to <code>target</code>.
|
||||
@@ -25,18 +34,8 @@ public class ChatService implements ChatCodes
|
||||
* @param target the username of the user to which the tell message
|
||||
* should be delivered.
|
||||
* @param message the contents of the message.
|
||||
* @param rsptarget the chat director reference that will receive the
|
||||
* tell response.
|
||||
*
|
||||
* @return the invocation request id of the generated tell request.
|
||||
* @param listener the reference that will receive the tell response.
|
||||
*/
|
||||
public static int tell (Client client, String target, String message,
|
||||
ChatDirector rsptarget)
|
||||
{
|
||||
InvocationDirector invdir = client.getInvocationDirector();
|
||||
Object[] args = new Object[] { target, message };
|
||||
Log.debug("Sending tell request [tgt=" + target +
|
||||
", msg=" + message + "].");
|
||||
return invdir.invoke(MODULE_NAME, TELL_REQUEST, args, rsptarget);
|
||||
}
|
||||
public void tell (Client client, String target, String message,
|
||||
TellListener listener);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// $Id: SpeakService.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* Provides a means by which "speaking" can be allowed among subscribers
|
||||
* of a particular distributed object.
|
||||
*/
|
||||
public interface SpeakService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Issues a request to speak "on" the distributed object via which
|
||||
* this speak service was provided.
|
||||
*
|
||||
* @param message the message to be spoken.
|
||||
* @param mode the "mode" of the message. This is an opaque value that
|
||||
* will be passed back down via the {@link ChatDirector} to the {@link
|
||||
* ChatDisplay} implementations which can interpret it in an
|
||||
* application specific manner. It's useful for differentiating
|
||||
* between regular speech, emotes, etc.
|
||||
*/
|
||||
public void speak (Client client, String message, byte mode);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ChatCodes.java,v 1.10 2002/07/26 20:35:01 ray Exp $
|
||||
// $Id: ChatCodes.java,v 1.11 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
@@ -10,19 +10,13 @@ import com.threerings.presents.data.InvocationCodes;
|
||||
*/
|
||||
public interface ChatCodes extends InvocationCodes
|
||||
{
|
||||
/** The module name for the chat services. */
|
||||
public static final String MODULE_NAME = "chat";
|
||||
|
||||
/** The chat localtype code for chat messages delivered on the place object
|
||||
* currently occupied by the client. This is the only type of chat
|
||||
* message that will be delivered unless the chat director is
|
||||
/** The chat localtype code for chat messages delivered on the place
|
||||
* object currently occupied by the client. This is the only type of
|
||||
* chat message that will be delivered unless the chat director is
|
||||
* explicitly provided with other chat message sources via {@link
|
||||
* ChatDirector#addAuxiliarySource}. */
|
||||
public static final String PLACE_CHAT_TYPE = "placeChat";
|
||||
|
||||
/** The message identifier for a speak request message. */
|
||||
public static final String SPEAK_REQUEST = "spkreq";
|
||||
|
||||
/** The message identifier for a speak notification message. */
|
||||
public static final String SPEAK_NOTIFICATION = "spknot";
|
||||
|
||||
@@ -32,31 +26,16 @@ public interface ChatCodes extends InvocationCodes
|
||||
/** The chat localtype for tells. */
|
||||
public static final String TELL_CHAT_TYPE = "tellChat";
|
||||
|
||||
/** The message identifier for a tell request. */
|
||||
public static final String TELL_REQUEST = "Tell";
|
||||
|
||||
/** The response identifier for a successful tell request. This is
|
||||
* mapped by the invocation services to a call to {@link
|
||||
* ChatDirector#handleTellSucceeded}. */
|
||||
public static final String TELL_SUCCEEDED_RESPONSE = "TellSucceeded";
|
||||
|
||||
/** The response identifier for a failed tell request. This is mapped
|
||||
* by the invocation services to a call to {@link
|
||||
* ChatDirector#handleTellFailed}. */
|
||||
public static final String TELL_FAILED_RESPONSE = "TellFailed";
|
||||
|
||||
/** The message identifier for a tell notification. */
|
||||
public static final String TELL_NOTIFICATION = "Tell";
|
||||
|
||||
/** The default mode used by speak requests. */
|
||||
/** The default mode used by {@link SpeakService#speak} requests. */
|
||||
public static final byte DEFAULT_MODE = 0;
|
||||
|
||||
/** The think mode to indicate that the user is thinking
|
||||
* what they're saying, or is it that they're saying what they're
|
||||
* thinking? */
|
||||
/** A {@link SpeakService#speak} mode to indicate that the user is
|
||||
* thinking what they're saying, or is it that they're saying what
|
||||
* they're thinking? */
|
||||
public static final byte THINK_MODE = 1;
|
||||
|
||||
/** The mode to indicate that a speak is actually an emote. */
|
||||
/** A {@link SpeakService#speak} mode to indicate that a speak is
|
||||
* actually an emote. */
|
||||
public static final byte EMOTE_MODE = 2;
|
||||
|
||||
/** An error code delivered when the user targeted for a tell
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// $Id: ChatMarshaller.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.crowd.chat.ChatService;
|
||||
import com.threerings.crowd.chat.ChatService.TellListener;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link ChatService} interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class ChatMarshaller extends InvocationMarshaller
|
||||
implements ChatService
|
||||
{
|
||||
// documentation inherited
|
||||
public static class TellMarshaller extends ListenerMarshaller
|
||||
implements TellListener
|
||||
{
|
||||
/** The method id used to dispatch {@link #tellSucceeded}
|
||||
* responses. */
|
||||
public static final int TELL_SUCCEEDED = 0;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void tellSucceeded ()
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, TELL_SUCCEEDED,
|
||||
new Object[] { }));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchResponse (int methodId, Object[] args)
|
||||
{
|
||||
switch (methodId) {
|
||||
case TELL_SUCCEEDED:
|
||||
((TellListener)listener).tellSucceeded(
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #tell} requests. */
|
||||
public static final int TELL = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void tell (Client arg1, String arg2, String arg3, TellListener arg4)
|
||||
{
|
||||
TellMarshaller listener4 = new TellMarshaller();
|
||||
listener4.listener = arg4;
|
||||
sendRequest(arg1, TELL, new Object[] {
|
||||
arg2, arg3, listener4
|
||||
});
|
||||
}
|
||||
|
||||
// Class file generated on 00:25:59 08/11/02.
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// $Id: SpeakMarshaller.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.crowd.chat.SpeakService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link SpeakService} interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class SpeakMarshaller extends InvocationMarshaller
|
||||
implements SpeakService
|
||||
{
|
||||
/** The method id used to dispatch {@link #speak} requests. */
|
||||
public static final int SPEAK = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void speak (Client arg1, String arg2, byte arg3)
|
||||
{
|
||||
sendRequest(arg1, SPEAK, new Object[] {
|
||||
arg2, new Byte(arg3)
|
||||
});
|
||||
}
|
||||
|
||||
// Class file generated on 19:01:34 08/12/02.
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id: ChatDispatcher.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.crowd.chat.ChatMarshaller;
|
||||
import com.threerings.crowd.chat.ChatService;
|
||||
import com.threerings.crowd.chat.ChatService.TellListener;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.server.InvocationDispatcher;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link ChatProvider}.
|
||||
*/
|
||||
public class ChatDispatcher extends InvocationDispatcher
|
||||
{
|
||||
/**
|
||||
* Creates a dispatcher that may be registered to dispatch invocation
|
||||
* service requests for the specified provider.
|
||||
*/
|
||||
public ChatDispatcher (ChatProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public InvocationMarshaller createMarshaller ()
|
||||
{
|
||||
return new ChatMarshaller();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchRequest (
|
||||
ClientObject source, int methodId, Object[] args)
|
||||
throws InvocationException
|
||||
{
|
||||
switch (methodId) {
|
||||
case ChatMarshaller.TELL:
|
||||
((ChatProvider)provider).tell(
|
||||
source,
|
||||
(String)args[0], (String)args[1], (TellListener)args[2]
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,70 @@
|
||||
//
|
||||
// $Id: ChatProvider.java,v 1.12 2002/07/22 22:54:03 ray Exp $
|
||||
// $Id: ChatProvider.java,v 1.13 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
import com.threerings.presents.dobj.MessageEvent;
|
||||
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
import com.threerings.presents.server.InvocationManager;
|
||||
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.Log;
|
||||
import com.threerings.crowd.chat.ChatService.TellListener;
|
||||
|
||||
/**
|
||||
* The chat provider handles the server side of the chat-related
|
||||
* invocation services.
|
||||
*/
|
||||
public class ChatProvider
|
||||
extends InvocationProvider implements ChatCodes
|
||||
implements ChatCodes, InvocationProvider
|
||||
{
|
||||
/**
|
||||
* Initializes the chat services and registers a chat provider with
|
||||
* the invocation manager.
|
||||
*/
|
||||
public static void init (InvocationManager invmgr, DObjectManager omgr)
|
||||
{
|
||||
_omgr = omgr;
|
||||
|
||||
// register a chat provider with the invocation manager
|
||||
invmgr.registerDispatcher(new ChatDispatcher(
|
||||
new ChatProvider()), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from a client to deliver a tell message to
|
||||
* another client.
|
||||
*/
|
||||
public void handleTellRequest (
|
||||
BodyObject source, int invid, String target, String message)
|
||||
public void tell (ClientObject caller, String target, String message,
|
||||
TellListener listener)
|
||||
throws InvocationException
|
||||
{
|
||||
// look up the target body object
|
||||
// make sure the target user is online
|
||||
BodyObject tobj = CrowdServer.lookupBody(target);
|
||||
if (tobj == null) {
|
||||
sendResponse(source, invid, TELL_FAILED_RESPONSE,
|
||||
USER_NOT_ONLINE);
|
||||
|
||||
} else {
|
||||
// deliver a tell notification to the target player
|
||||
sendTellMessage(tobj.getOid(), source.username, null, message);
|
||||
// let the teller know it went ok
|
||||
sendResponse(source, invid, TELL_SUCCEEDED_RESPONSE);
|
||||
throw new InvocationException(USER_NOT_ONLINE);
|
||||
}
|
||||
|
||||
// deliver a tell notification to the target player
|
||||
BodyObject source = (BodyObject)caller;
|
||||
sendTellMessage(tobj, source.username, null, message);
|
||||
|
||||
// let the teller know it went ok
|
||||
listener.tellSucceeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivers a tell notification to the specified target player,
|
||||
* originating with the specified speaker.
|
||||
*
|
||||
* @param targetOid the body object id of the user that will receive
|
||||
* the tell message.
|
||||
* @param target the body object of the user that will receive the
|
||||
* tell message.
|
||||
* @param speaker the username of the user that generated the message
|
||||
* (or some special speaker name for server messages).
|
||||
* @param bundle the bundle identifier that will be used by the client
|
||||
@@ -54,89 +74,11 @@ public class ChatProvider
|
||||
* @param message the text of the chat message.
|
||||
*/
|
||||
public static void sendTellMessage (
|
||||
int targetOid, String speaker, String bundle, String message)
|
||||
BodyObject target, String speaker, String bundle, String message)
|
||||
{
|
||||
Object[] args = null;
|
||||
if (bundle == null) {
|
||||
args = new Object[] { speaker, message };
|
||||
} else {
|
||||
args = new Object[] { speaker, bundle, message };
|
||||
}
|
||||
CrowdServer.invmgr.sendNotification(
|
||||
targetOid, MODULE_NAME, TELL_NOTIFICATION, args);
|
||||
ChatSender.sendTell(target, speaker, bundle, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a chat 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 placeOid the place to which to deliver the chat 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 chat message.
|
||||
*/
|
||||
public static void sendChatMessage (
|
||||
int placeOid, String speaker, String bundle, String message)
|
||||
{
|
||||
sendChatMessage(
|
||||
placeOid, speaker, bundle, message, ChatCodes.DEFAULT_MODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a chat 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 placeOid the place to which to deliver the chat 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 chat message.
|
||||
* @param mode the mode of the message, @see ChatCodes.DEFAULT_MODE
|
||||
*/
|
||||
public static void sendChatMessage (
|
||||
int placeOid, String speaker, String bundle, String message,
|
||||
byte mode)
|
||||
{
|
||||
Object[] outargs = null;
|
||||
if (bundle == null) {
|
||||
outargs = new Object[] { speaker, message, new Byte(mode) };
|
||||
} else {
|
||||
outargs = new Object[] { speaker, bundle, message, new Byte(mode) };
|
||||
}
|
||||
MessageEvent nevt = new MessageEvent(
|
||||
placeOid, ChatService.SPEAK_NOTIFICATION, outargs);
|
||||
CrowdServer.omgr.postEvent(nevt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a system message notification to the specified place object
|
||||
* with the supplied message content. A system message is one that
|
||||
* will be rendered where the chat messages are rendered, but in a way
|
||||
* that makes it clear that it is a message from the server.
|
||||
*
|
||||
* @param placeOid the place to 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 sendSystemMessage (
|
||||
int placeOid, String bundle, String message)
|
||||
{
|
||||
Object[] outargs = new Object[] { bundle, message };
|
||||
MessageEvent nevt = new MessageEvent(
|
||||
placeOid, ChatService.SYSTEM_NOTIFICATION, outargs);
|
||||
CrowdServer.omgr.postEvent(nevt);
|
||||
}
|
||||
/** The distributed object manager used by the chat services. */
|
||||
protected static DObjectManager _omgr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// $Id: ChatSender.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.crowd.chat.ChatDecoder;
|
||||
import com.threerings.crowd.chat.ChatReceiver;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.server.InvocationSender;
|
||||
|
||||
/**
|
||||
* Used to issue notifications to a {@link ChatReceiver} instance on a
|
||||
* client.
|
||||
*/
|
||||
public class ChatSender extends InvocationSender
|
||||
{
|
||||
/**
|
||||
* Issues a notification that will result in a call to {@link
|
||||
* ChatReceiver#receivedTell} on a client.
|
||||
*/
|
||||
public static void sendTell (
|
||||
ClientObject target, String arg1, String arg2, String arg3)
|
||||
{
|
||||
sendNotification(
|
||||
target, ChatDecoder.RECEIVER_CODE, ChatDecoder.RECEIVED_TELL,
|
||||
new Object[] { arg1, arg2, arg3 });
|
||||
}
|
||||
|
||||
// Generated on 11:25:46 08/12/02.
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// $Id: SpeakDispatcher.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.crowd.chat.SpeakMarshaller;
|
||||
import com.threerings.crowd.chat.SpeakService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.server.InvocationDispatcher;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link SpeakProvider}.
|
||||
*/
|
||||
public class SpeakDispatcher extends InvocationDispatcher
|
||||
{
|
||||
/**
|
||||
* Creates a dispatcher that may be registered to dispatch invocation
|
||||
* service requests for the specified provider.
|
||||
*/
|
||||
public SpeakDispatcher (SpeakProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public InvocationMarshaller createMarshaller ()
|
||||
{
|
||||
return new SpeakMarshaller();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchRequest (
|
||||
ClientObject source, int methodId, Object[] args)
|
||||
throws InvocationException
|
||||
{
|
||||
switch (methodId) {
|
||||
case SpeakMarshaller.SPEAK:
|
||||
((SpeakProvider)provider).speak(
|
||||
source,
|
||||
(String)args[0], ((Byte)args[1]).byteValue()
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// $Id: SpeakProvider.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.chat;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.MessageEvent;
|
||||
import com.threerings.presents.server.InvocationProvider;
|
||||
|
||||
import com.threerings.crowd.Log;
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
/**
|
||||
* Provides the back-end of the chat speaking facilities. A server entity
|
||||
* 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
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a {@link SpeakService#speak} request.
|
||||
*/
|
||||
public void speak (ClientObject caller, String message, byte mode)
|
||||
{
|
||||
// ensure that the speaker is valid
|
||||
if (!_validator.isValidSpeaker(_speakObj, caller)) {
|
||||
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, ((BodyObject)caller).username,
|
||||
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, String 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, String speaker,
|
||||
String bundle, String message, byte mode)
|
||||
{
|
||||
Object[] outargs = null;
|
||||
if (bundle == null) {
|
||||
outargs = new Object[] { speaker, message, new Byte(mode) };
|
||||
} else {
|
||||
outargs = new Object[] { speaker, bundle, message, new Byte(mode) };
|
||||
}
|
||||
speakObj.postEvent(
|
||||
new MessageEvent(speakObj.getOid(), SPEAK_NOTIFICATION, outargs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a system 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.
|
||||
*
|
||||
* @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 sendSystemSpeak (
|
||||
DObject speakObj, String bundle, String message)
|
||||
{
|
||||
speakObj.postEvent(
|
||||
new MessageEvent(speakObj.getOid(), SYSTEM_NOTIFICATION,
|
||||
new Object[] { bundle, message }));
|
||||
}
|
||||
|
||||
/** Our speech object. */
|
||||
protected DObject _speakObj;
|
||||
|
||||
/** The entity that will validate our speakers. */
|
||||
protected SpeakerValidator _validator;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id: LocationDecoder.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.client;
|
||||
|
||||
import com.threerings.crowd.client.LocationReceiver;
|
||||
import com.threerings.presents.client.InvocationDecoder;
|
||||
|
||||
/**
|
||||
* Dispatches calls to a {@link LocationReceiver} instance.
|
||||
*/
|
||||
public class LocationDecoder extends InvocationDecoder
|
||||
{
|
||||
/** The generated hash code used to identify this receiver class. */
|
||||
public static final String RECEIVER_CODE = "58f2830e027f4f3377e100ef12332497";
|
||||
|
||||
/** The method id used to dispatch {@link LocationReceiver#forcedMove}
|
||||
* notifications. */
|
||||
public static final int FORCED_MOVE = 1;
|
||||
|
||||
/**
|
||||
* Creates a decoder that may be registered to dispatch invocation
|
||||
* service notifications to the specified receiver.
|
||||
*/
|
||||
public LocationDecoder (LocationReceiver receiver)
|
||||
{
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getReceiverCode ()
|
||||
{
|
||||
return RECEIVER_CODE;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchNotification (int methodId, Object[] args)
|
||||
{
|
||||
switch (methodId) {
|
||||
case FORCED_MOVE:
|
||||
((LocationReceiver)receiver).forcedMove(
|
||||
((Integer)args[0]).intValue()
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchNotification(methodId, args);
|
||||
}
|
||||
}
|
||||
|
||||
// Generated on 11:25:46 08/12/02.
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: LocationDirector.java,v 1.24 2002/06/14 01:40:16 ray Exp $
|
||||
// $Id: LocationDirector.java,v 1.25 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.client;
|
||||
|
||||
@@ -10,9 +10,9 @@ import com.samskivert.util.ObserverList;
|
||||
import com.samskivert.util.ObserverList.ObserverOp;
|
||||
import com.samskivert.util.ResultListener;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
import com.threerings.presents.client.SessionObserver;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
import com.threerings.presents.dobj.ObjectAccessException;
|
||||
@@ -32,8 +32,9 @@ import com.threerings.crowd.util.CrowdContext;
|
||||
* provides a mechanism for ratifying a request to move to a new place
|
||||
* before actually issuing the request.
|
||||
*/
|
||||
public class LocationDirector
|
||||
implements LocationCodes, SessionObserver, Subscriber, InvocationReceiver
|
||||
public class LocationDirector extends BasicDirector
|
||||
implements LocationCodes, Subscriber, LocationReceiver,
|
||||
LocationService.MoveListener
|
||||
{
|
||||
/**
|
||||
* Used to recover from a moveTo request that was accepted but
|
||||
@@ -55,15 +56,14 @@ public class LocationDirector
|
||||
*/
|
||||
public LocationDirector (CrowdContext ctx)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
// keep this around for later
|
||||
_ctx = ctx;
|
||||
|
||||
// register ourselves as a client observer
|
||||
ctx.getClient().addClientObserver(this);
|
||||
|
||||
// register for location notifications
|
||||
_ctx.getClient().getInvocationDirector().registerReceiver(
|
||||
MODULE_NAME, this);
|
||||
new LocationDecoder(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +137,7 @@ public class LocationDirector
|
||||
_pendingPlaceId = placeId;
|
||||
|
||||
// issue a moveTo request
|
||||
LocationService.moveTo(_ctx.getClient(), placeId, this);
|
||||
_lservice.moveTo(_ctx.getClient(), placeId, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -314,7 +314,9 @@ public class LocationDirector
|
||||
// documentation inherited from interface
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
// get a copy of our body object
|
||||
super.clientDidLogon(client);
|
||||
|
||||
// subscribe to our body object
|
||||
Subscriber sub = new Subscriber() {
|
||||
public void objectAvailable (DObject object)
|
||||
{
|
||||
@@ -332,6 +334,14 @@ public class LocationDirector
|
||||
client.getDObjectManager().subscribeToObject(cloid, sub);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void fetchServices (Client client)
|
||||
{
|
||||
// obtain our service handle
|
||||
_lservice = (LocationService)
|
||||
client.requireService(LocationService.class);
|
||||
}
|
||||
|
||||
protected void gotBodyObject (BodyObject clobj)
|
||||
{
|
||||
// check to see if we are already in a location, in which case
|
||||
@@ -341,17 +351,19 @@ public class LocationDirector
|
||||
// documentation inherited from interface
|
||||
public void clientDidLogoff (Client client)
|
||||
{
|
||||
super.clientDidLogoff(client);
|
||||
|
||||
// clear ourselves out and inform observers of our departure
|
||||
didLeavePlace();
|
||||
|
||||
// let our observers know that we're no longer in a location
|
||||
_observers.apply(_didChangeOp);
|
||||
|
||||
_lservice = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a successful <code>moveTo</code> request.
|
||||
*/
|
||||
public void handleMoveSucceeded (int invid, PlaceConfig config)
|
||||
// documentation inherited from interface
|
||||
public void moveSucceeded (PlaceConfig config)
|
||||
{
|
||||
// handle the successful move
|
||||
didMoveTo(_pendingPlaceId, config);
|
||||
@@ -360,10 +372,8 @@ public class LocationDirector
|
||||
_pendingPlaceId = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a failed <code>moveTo</code> request.
|
||||
*/
|
||||
public void handleMoveFailed (int invid, String reason)
|
||||
// documentation inherited from interface
|
||||
public void requestFailed (String reason)
|
||||
{
|
||||
// clear out our pending request oid
|
||||
int placeId = _pendingPlaceId;
|
||||
@@ -376,13 +386,8 @@ public class LocationDirector
|
||||
notifyFailure(placeId, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the server has decided to forcibly move us to another
|
||||
* room. The server first ejects us from our previous room and then
|
||||
* sends us a notification with our new location. We then turn around
|
||||
* and issue a standard moveTo request.
|
||||
*/
|
||||
public void handleMoveNotification (int placeId)
|
||||
// documentation inherited from interface
|
||||
public void forcedMove (int placeId)
|
||||
{
|
||||
Log.info("Moving at request of server [placeId=" + placeId + "].");
|
||||
|
||||
@@ -493,6 +498,9 @@ public class LocationDirector
|
||||
/** The context through which we access needed services. */
|
||||
protected CrowdContext _ctx;
|
||||
|
||||
/** Provides access to location services. */
|
||||
protected LocationService _lservice;
|
||||
|
||||
/** Our location observer list. */
|
||||
protected ObserverList _observers =
|
||||
new ObserverList(ObserverList.SAFE_IN_ORDER_NOTIFY);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// $Id: LocationReceiver.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.client;
|
||||
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
|
||||
/**
|
||||
* Defines, for the location services, a set of notifications delivered
|
||||
* asynchronously by the server to the client.
|
||||
*/
|
||||
public interface LocationReceiver extends InvocationReceiver
|
||||
{
|
||||
/**
|
||||
* Used to communicate a required move notification to the client. The
|
||||
* server will have removed the client from their existing location
|
||||
* and the client is then responsible for generating a {@link
|
||||
* LocationService#moveTo} request to move to the new location.
|
||||
*/
|
||||
public void forcedMove (int placeId);
|
||||
}
|
||||
@@ -1,33 +1,43 @@
|
||||
//
|
||||
// $Id: LocationService.java,v 1.6 2002/05/15 23:54:34 mdb Exp $
|
||||
// $Id: LocationService.java,v 1.7 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.client;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationDirector;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.crowd.Log;
|
||||
import com.threerings.crowd.data.LocationCodes;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
/**
|
||||
* The location services provide a mechanism by which the client can
|
||||
* request to move from place to place in the server. These services
|
||||
* should not be used directly, but instead should be accessed via the
|
||||
* location director.
|
||||
*
|
||||
* @see LocationDirector
|
||||
* {@link LocationDirector}.
|
||||
*/
|
||||
public class LocationService implements LocationCodes
|
||||
public interface LocationService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Requests that that this client's body be moved to the specified
|
||||
* location.
|
||||
* Used to communicate responses to {@link #moveTo} requests.
|
||||
*/
|
||||
public static void moveTo (Client client, int placeId,
|
||||
LocationDirector rsptarget)
|
||||
public static interface MoveListener extends InvocationListener
|
||||
{
|
||||
InvocationDirector invdir = client.getInvocationDirector();
|
||||
Object[] args = new Object[] { new Integer(placeId) };
|
||||
invdir.invoke(MODULE_NAME, MOVE_TO_REQUEST, args, rsptarget);
|
||||
Log.debug("Sent moveTo request [place=" + placeId + "].");
|
||||
/**
|
||||
* Called in response to a successful {@link #moveTo} request.
|
||||
*/
|
||||
public void moveSucceeded (PlaceConfig config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that this client's body be moved to the specified
|
||||
* location.
|
||||
*
|
||||
* @param client a reference to the client object that defines the
|
||||
* context in which this invocation service should be executed.
|
||||
* @param placeId the object id of the place object to which the body
|
||||
* should be moved.
|
||||
* @param listener the listener that will be informed of success or
|
||||
* failure.
|
||||
*/
|
||||
public void moveTo (Client client, int placeId, MoveListener listener);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: BodyObject.dobj,v 1.9 2002/06/20 22:37:32 mdb Exp $
|
||||
// $Id: BodyObject.dobj,v 1.10 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
@@ -18,9 +18,7 @@ public class BodyObject extends ClientObject
|
||||
*/
|
||||
public int location = -1;
|
||||
|
||||
/**
|
||||
* Returns a short string identifying this body.
|
||||
*/
|
||||
// documentation inherited
|
||||
public String who ()
|
||||
{
|
||||
return username + " (" + getOid() + ")";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: BodyObject.java,v 1.3 2002/06/20 22:37:32 mdb Exp $
|
||||
// $Id: BodyObject.java,v 1.4 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
@@ -24,9 +24,7 @@ public class BodyObject extends ClientObject
|
||||
*/
|
||||
public int location = -1;
|
||||
|
||||
/**
|
||||
* Returns a short string identifying this body.
|
||||
*/
|
||||
// documentation inherited
|
||||
public String who ()
|
||||
{
|
||||
return username + " (" + getOid() + ")";
|
||||
|
||||
@@ -1,35 +1,15 @@
|
||||
//
|
||||
// $Id: LocationCodes.java,v 1.3 2002/05/26 02:24:46 mdb Exp $
|
||||
// $Id: LocationCodes.java,v 1.4 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
import com.threerings.crowd.client.LocationDirector;
|
||||
|
||||
/**
|
||||
* Contains codes used by the location invocation services.
|
||||
*/
|
||||
public interface LocationCodes extends InvocationCodes
|
||||
{
|
||||
/** The module name for the location services. */
|
||||
public static final String MODULE_NAME = "location";
|
||||
|
||||
/** The message identifier for a moveTo request. */
|
||||
public static final String MOVE_TO_REQUEST = "MoveTo";
|
||||
|
||||
/** The response identifier for a successful moveTo request. This is
|
||||
* mapped by the invocation services to a call to {@link
|
||||
* LocationDirector#handleMoveSucceeded}. */
|
||||
public static final String MOVE_SUCCEEDED_RESPONSE = "MoveSucceeded";
|
||||
|
||||
/** The response identifier for a failed moveTo request. This is
|
||||
* mapped by the invocation services to a call to {@link
|
||||
* LocationDirector#handleMoveFailed}. */
|
||||
public static final String MOVE_FAILED_RESPONSE = "MoveFailed";
|
||||
|
||||
/** The message identifier for a move notification. */
|
||||
public static final String MOVE_NOTIFICATION = "Move";
|
||||
|
||||
/** An error code indicating that a place identified by a particular
|
||||
* place id does not exist. Usually generated by a failed moveTo
|
||||
* request. */
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// $Id: LocationMarshaller.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
import com.threerings.crowd.client.LocationService;
|
||||
import com.threerings.crowd.client.LocationService.MoveListener;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link LocationService} interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class LocationMarshaller extends InvocationMarshaller
|
||||
implements LocationService
|
||||
{
|
||||
// documentation inherited
|
||||
public static class MoveMarshaller extends ListenerMarshaller
|
||||
implements MoveListener
|
||||
{
|
||||
/** The method id used to dispatch {@link #moveSucceeded}
|
||||
* responses. */
|
||||
public static final int MOVE_SUCCEEDED = 0;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceeded (PlaceConfig arg1)
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, MOVE_SUCCEEDED,
|
||||
new Object[] { arg1 }));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchResponse (int methodId, Object[] args)
|
||||
{
|
||||
switch (methodId) {
|
||||
case MOVE_SUCCEEDED:
|
||||
((MoveListener)listener).moveSucceeded(
|
||||
(PlaceConfig)args[0]);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #moveTo} requests. */
|
||||
public static final int MOVE_TO = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveTo (Client arg1, int arg2, MoveListener arg3)
|
||||
{
|
||||
MoveMarshaller listener3 = new MoveMarshaller();
|
||||
listener3.listener = arg3;
|
||||
sendRequest(arg1, MOVE_TO, new Object[] {
|
||||
new Integer(arg2), listener3
|
||||
});
|
||||
}
|
||||
|
||||
// Class file generated on 00:25:59 08/11/02.
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: OccupantInfo.java,v 1.8 2002/07/23 05:54:52 mdb Exp $
|
||||
// $Id: OccupantInfo.java,v 1.9 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
@@ -40,7 +40,7 @@ public class OccupantInfo extends SimpleStreamableObject
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object getKey ()
|
||||
public Comparable getKey ()
|
||||
{
|
||||
return bodyOid;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
//
|
||||
// $Id: PlaceObject.dobj,v 1.9 2002/04/15 14:30:49 shaper Exp $
|
||||
// $Id: PlaceObject.dobj,v 1.10 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
import com.threerings.presents.dobj.*;
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.presents.dobj.OidList;
|
||||
|
||||
import com.threerings.crowd.chat.SpeakMarshaller;
|
||||
|
||||
public class PlaceObject extends DObject
|
||||
{
|
||||
@@ -19,4 +23,7 @@ public class PlaceObject extends DObject
|
||||
* to be known by everyone in the place.
|
||||
*/
|
||||
public DSet occupantInfo = new DSet();
|
||||
|
||||
/** Used to generate speak requests on this place object. */
|
||||
public SpeakMarshaller speakService;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
//
|
||||
// $Id: PlaceObject.java,v 1.6 2002/04/15 14:35:31 shaper Exp $
|
||||
// $Id: PlaceObject.java,v 1.7 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.data;
|
||||
|
||||
import com.threerings.presents.dobj.*;
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.presents.dobj.OidList;
|
||||
|
||||
import com.threerings.crowd.chat.SpeakMarshaller;
|
||||
|
||||
public class PlaceObject extends DObject
|
||||
{
|
||||
@@ -13,6 +17,9 @@ public class PlaceObject extends DObject
|
||||
/** The field name of the <code>occupantInfo</code> field. */
|
||||
public static final String OCCUPANT_INFO = "occupantInfo";
|
||||
|
||||
/** The field name of the <code>speakService</code> field. */
|
||||
public static final String SPEAK_SERVICE = "speakService";
|
||||
|
||||
/**
|
||||
* Tracks the oid of the body objects of all of the occupants of this
|
||||
* place.
|
||||
@@ -26,6 +33,9 @@ public class PlaceObject extends DObject
|
||||
*/
|
||||
public DSet occupantInfo = new DSet();
|
||||
|
||||
/** Used to generate speak requests on this place object. */
|
||||
public SpeakMarshaller speakService;
|
||||
|
||||
/**
|
||||
* Requests that the specified oid be added to the
|
||||
* <code>occupants</code> oid list. The list will not change until the
|
||||
@@ -91,4 +101,18 @@ public class PlaceObject extends DObject
|
||||
this.occupantInfo = occupantInfo;
|
||||
requestAttributeChange(OCCUPANT_INFO, occupantInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>speakService</code> field be set to the specified
|
||||
* value. The local value will be updated immediately and an event
|
||||
* will be propagated through the system to notify all listeners that
|
||||
* the attribute did change. Proxied copies of this object (on
|
||||
* clients) will apply the value change when they received the
|
||||
* attribute changed notification.
|
||||
*/
|
||||
public void setSpeakService (SpeakMarshaller speakService)
|
||||
{
|
||||
this.speakService = speakService;
|
||||
requestAttributeChange(SPEAK_SERVICE, speakService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: CrowdServer.java,v 1.12 2002/04/18 00:44:50 shaper Exp $
|
||||
// $Id: CrowdServer.java,v 1.13 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.server;
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Iterator;
|
||||
import com.threerings.presents.server.PresentsServer;
|
||||
|
||||
import com.threerings.crowd.Log;
|
||||
import com.threerings.crowd.chat.ChatProvider;
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
/**
|
||||
@@ -40,10 +41,13 @@ public class CrowdServer extends PresentsServer
|
||||
// create our place registry
|
||||
plreg = new PlaceRegistry(invmgr, omgr);
|
||||
|
||||
// register our invocation service providers
|
||||
String[] providers = null;
|
||||
providers = CrowdConfig.config.getValue(PROVIDERS_KEY, providers);
|
||||
registerProviders(providers);
|
||||
// initialize the chat services
|
||||
ChatProvider.init(invmgr, omgr);
|
||||
|
||||
// // register our invocation service providers
|
||||
// String[] providers = null;
|
||||
// providers = CrowdConfig.config.getValue(PROVIDERS_KEY, providers);
|
||||
// registerProviders(providers);
|
||||
|
||||
Log.info("Crowd server initialized.");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// $Id: LocationDispatcher.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.server;
|
||||
|
||||
import com.threerings.crowd.client.LocationService;
|
||||
import com.threerings.crowd.client.LocationService.MoveListener;
|
||||
import com.threerings.crowd.data.LocationMarshaller;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.server.InvocationDispatcher;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link LocationProvider}.
|
||||
*/
|
||||
public class LocationDispatcher extends InvocationDispatcher
|
||||
{
|
||||
/**
|
||||
* Creates a dispatcher that may be registered to dispatch invocation
|
||||
* service requests for the specified provider.
|
||||
*/
|
||||
public LocationDispatcher (LocationProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public InvocationMarshaller createMarshaller ()
|
||||
{
|
||||
return new LocationMarshaller();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchRequest (
|
||||
ClientObject source, int methodId, Object[] args)
|
||||
throws InvocationException
|
||||
{
|
||||
switch (methodId) {
|
||||
case LocationMarshaller.MOVE_TO:
|
||||
((LocationProvider)provider).moveTo(
|
||||
source,
|
||||
((Integer)args[0]).intValue(), (MoveListener)args[1]
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,19 @@
|
||||
//
|
||||
// $Id: LocationProvider.java,v 1.15 2002/06/20 22:38:58 mdb Exp $
|
||||
// $Id: LocationProvider.java,v 1.16 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.server;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.RootDObjectManager;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
import com.threerings.presents.server.InvocationManager;
|
||||
import com.threerings.presents.server.InvocationProvider;
|
||||
import com.threerings.presents.server.ServiceFailedException;
|
||||
|
||||
import com.threerings.crowd.Log;
|
||||
import com.threerings.crowd.client.LocationService;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.LocationCodes;
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
@@ -20,42 +23,38 @@ import com.threerings.crowd.data.PlaceObject;
|
||||
/**
|
||||
* This class provides the server end of the location services.
|
||||
*/
|
||||
public class LocationProvider extends InvocationProvider
|
||||
implements LocationCodes
|
||||
public class LocationProvider
|
||||
implements LocationCodes, InvocationProvider
|
||||
{
|
||||
/**
|
||||
* Constructs a location provider and registers it with the invocation
|
||||
* manager to handle location services. This is done automatically by
|
||||
* the {@link PlaceRegistry}.
|
||||
* Creates a location provider and prepares it for operation.
|
||||
*/
|
||||
public static void init (
|
||||
InvocationManager invmgr, RootDObjectManager omgr, PlaceRegistry plreg)
|
||||
public LocationProvider (InvocationManager invmgr, RootDObjectManager omgr,
|
||||
PlaceRegistry plreg)
|
||||
{
|
||||
// we'll need these later
|
||||
_invmgr = invmgr;
|
||||
_omgr = omgr;
|
||||
_plreg = plreg;
|
||||
|
||||
// register a location provider instance
|
||||
invmgr.registerProvider(MODULE_NAME, new LocationProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from a client to move to a new place.
|
||||
* Requests that this client's body be moved to the specified
|
||||
* location.
|
||||
*
|
||||
* @param caller the client object of the client that invoked this
|
||||
* remotely callable method.
|
||||
* @param placeId the object id of the place object to which the body
|
||||
* should be moved.
|
||||
* @param listener the listener that will be informed of success or
|
||||
* failure.
|
||||
*/
|
||||
public void handleMoveToRequest (
|
||||
BodyObject source, int invid, int placeId)
|
||||
public void moveTo (ClientObject caller, int placeId,
|
||||
LocationService.MoveListener listener)
|
||||
throws InvocationException
|
||||
{
|
||||
try {
|
||||
// do the move
|
||||
PlaceConfig config = moveTo(source, placeId);
|
||||
// and send the response
|
||||
sendResponse(source, invid, MOVE_SUCCEEDED_RESPONSE, config);
|
||||
|
||||
} catch (ServiceFailedException sfe) {
|
||||
sendResponse(source, invid, MOVE_FAILED_RESPONSE,
|
||||
sfe.getMessage());
|
||||
}
|
||||
// do the move and send the response
|
||||
listener.moveSucceeded(moveTo((BodyObject)caller, placeId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,8 +67,8 @@ public class LocationProvider extends InvocationProvider
|
||||
* successful for some reason (which will be communicated as an error
|
||||
* code in the exception's message data).
|
||||
*/
|
||||
public static PlaceConfig moveTo (BodyObject source, int placeId)
|
||||
throws ServiceFailedException
|
||||
public PlaceConfig moveTo (BodyObject source, int placeId)
|
||||
throws InvocationException
|
||||
{
|
||||
int bodoid = source.getOid();
|
||||
|
||||
@@ -78,7 +77,7 @@ public class LocationProvider extends InvocationProvider
|
||||
if (pmgr == null) {
|
||||
Log.info("Requested to move to non-existent place " +
|
||||
"[source=" + source + ", place=" + placeId + "].");
|
||||
throw new ServiceFailedException(NO_SUCH_PLACE);
|
||||
throw new InvocationException(NO_SUCH_PLACE);
|
||||
}
|
||||
|
||||
// if they're already in the location they're asking to move to,
|
||||
@@ -97,26 +96,17 @@ public class LocationProvider extends InvocationProvider
|
||||
if (!source.acquireLock("moveToLock")) {
|
||||
// if we're still locked, a previous moveTo request hasn't
|
||||
// been fully processed
|
||||
throw new ServiceFailedException(MOVE_IN_PROGRESS);
|
||||
throw new InvocationException(MOVE_IN_PROGRESS);
|
||||
}
|
||||
|
||||
PlaceObject place = pmgr.getPlaceObject();
|
||||
try {
|
||||
place.startTransaction();
|
||||
source.startTransaction();
|
||||
|
||||
// remove them from any previous location
|
||||
leaveOccupiedPlace(source);
|
||||
|
||||
// set the body's new location
|
||||
source.setLocation(place.getOid());
|
||||
|
||||
} finally {
|
||||
source.commitTransaction();
|
||||
}
|
||||
|
||||
try {
|
||||
place.startTransaction();
|
||||
|
||||
// generate a new occupant info record and add it to the
|
||||
// target location
|
||||
OccupantInfo info = pmgr.buildOccupantInfo(source);
|
||||
@@ -124,11 +114,15 @@ public class LocationProvider extends InvocationProvider
|
||||
place.addToOccupantInfo(info);
|
||||
}
|
||||
|
||||
// set the body's new location
|
||||
source.setLocation(place.getOid());
|
||||
|
||||
// add the body oid to the place object's occupant list
|
||||
place.addToOccupants(bodoid);
|
||||
|
||||
} finally {
|
||||
place.commitTransaction();
|
||||
source.commitTransaction();
|
||||
}
|
||||
|
||||
} finally {
|
||||
@@ -144,7 +138,7 @@ public class LocationProvider extends InvocationProvider
|
||||
* Removes the specified body from the place object they currently
|
||||
* occupy. Does nothing if the body is not currently in a place.
|
||||
*/
|
||||
public static void leaveOccupiedPlace (BodyObject source)
|
||||
public void leaveOccupiedPlace (BodyObject source)
|
||||
{
|
||||
int oldloc = source.location;
|
||||
int bodoid = source.getOid();
|
||||
@@ -200,18 +194,16 @@ public class LocationProvider extends InvocationProvider
|
||||
// first remove them from their old place
|
||||
leaveOccupiedPlace(source);
|
||||
|
||||
// then send a move notification
|
||||
_invmgr.sendNotification(
|
||||
source.getOid(), MODULE_NAME, MOVE_NOTIFICATION,
|
||||
new Object[] { new Integer(placeId) });
|
||||
// then send a forced move notification
|
||||
LocationSender.forcedMove(source, placeId);
|
||||
}
|
||||
|
||||
/** The invocation manager with which we interoperate. */
|
||||
protected static InvocationManager _invmgr;
|
||||
protected InvocationManager _invmgr;
|
||||
|
||||
/** The distributed object manager with which we interoperate. */
|
||||
protected static RootDObjectManager _omgr;
|
||||
protected RootDObjectManager _omgr;
|
||||
|
||||
/** The place registry with which we interoperate. */
|
||||
protected static PlaceRegistry _plreg;
|
||||
protected PlaceRegistry _plreg;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// $Id: LocationSender.java,v 1.1 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.server;
|
||||
|
||||
import com.threerings.crowd.client.LocationDecoder;
|
||||
import com.threerings.crowd.client.LocationReceiver;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.server.InvocationSender;
|
||||
|
||||
/**
|
||||
* Used to issue notifications to a {@link LocationReceiver} instance on a
|
||||
* client.
|
||||
*/
|
||||
public class LocationSender extends InvocationSender
|
||||
{
|
||||
/**
|
||||
* Issues a notification that will result in a call to {@link
|
||||
* LocationReceiver#forcedMove} on a client.
|
||||
*/
|
||||
public static void forcedMove (
|
||||
ClientObject target, int arg1)
|
||||
{
|
||||
sendNotification(
|
||||
target, LocationDecoder.RECEIVER_CODE, LocationDecoder.FORCED_MOVE,
|
||||
new Object[] { new Integer(arg1) });
|
||||
}
|
||||
|
||||
// Generated on 11:25:46 08/12/02.
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: PlaceManager.java,v 1.31 2002/06/20 22:12:22 mdb Exp $
|
||||
// $Id: PlaceManager.java,v 1.32 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.server;
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.server.InvocationManager;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
import com.threerings.presents.dobj.MessageEvent;
|
||||
import com.threerings.presents.dobj.MessageListener;
|
||||
@@ -22,6 +26,10 @@ import com.threerings.crowd.data.OccupantInfo;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.crowd.chat.SpeakDispatcher;
|
||||
import com.threerings.crowd.chat.SpeakMarshaller;
|
||||
import com.threerings.crowd.chat.SpeakProvider;
|
||||
|
||||
/**
|
||||
* The place manager is the server-side entity that handles all
|
||||
* place-related interaction. It subscribes to the place object and reacts
|
||||
@@ -42,7 +50,8 @@ import com.threerings.crowd.data.PlaceObject;
|
||||
* listeners.
|
||||
*/
|
||||
public class PlaceManager
|
||||
implements MessageListener, OidListListener, ObjectDeathListener
|
||||
implements MessageListener, OidListListener, ObjectDeathListener,
|
||||
SpeakProvider.SpeakerValidator
|
||||
{
|
||||
/**
|
||||
* An interface used to allow the registration of standard message
|
||||
@@ -99,11 +108,13 @@ public class PlaceManager
|
||||
* Called by the place registry after creating this place manager.
|
||||
*/
|
||||
public void init (
|
||||
PlaceRegistry registry, PlaceConfig config, DObjectManager omgr)
|
||||
PlaceRegistry registry, InvocationManager invmgr,
|
||||
DObjectManager omgr, PlaceConfig config)
|
||||
{
|
||||
_registry = registry;
|
||||
_config = config;
|
||||
_invmgr = invmgr;
|
||||
_omgr = omgr;
|
||||
_config = config;
|
||||
|
||||
// let derived classes do initialization stuff
|
||||
didInit();
|
||||
@@ -135,6 +146,13 @@ public class PlaceManager
|
||||
// keep track of this
|
||||
_plobj = plobj;
|
||||
|
||||
// create and register a speaker service instance that clients can
|
||||
// use to speak in this place
|
||||
SpeakMarshaller speakService =
|
||||
(SpeakMarshaller)_invmgr.registerDispatcher(
|
||||
new SpeakDispatcher(new SpeakProvider(_plobj, this)), false);
|
||||
plobj.setSpeakService(speakService);
|
||||
|
||||
// we'll need to hear about place object events
|
||||
plobj.addListener(this);
|
||||
|
||||
@@ -379,6 +397,13 @@ public class PlaceManager
|
||||
didShutdown();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean isValidSpeaker (DObject speakObj, ClientObject speaker)
|
||||
{
|
||||
// only allow people in the room to speak
|
||||
return _plobj.occupants.contains(speaker.getOid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this manager. Does so in a way
|
||||
* that makes it easier for derived classes to add to the string
|
||||
@@ -438,6 +463,13 @@ public class PlaceManager
|
||||
}
|
||||
}
|
||||
|
||||
/** A reference to the place registry with which we're registered. */
|
||||
protected PlaceRegistry _registry;
|
||||
|
||||
/** The invocation manager with whom we register our game invocation
|
||||
* services. */
|
||||
protected InvocationManager _invmgr;
|
||||
|
||||
/** A distributed object manager for doing dobj stuff. */
|
||||
protected DObjectManager _omgr;
|
||||
|
||||
@@ -447,9 +479,6 @@ public class PlaceManager
|
||||
/** A reference to the configuration for our place. */
|
||||
protected PlaceConfig _config;
|
||||
|
||||
/** A reference to the place registry with which we're registered. */
|
||||
protected PlaceRegistry _registry;
|
||||
|
||||
/** Message handlers are used to process message events. */
|
||||
protected HashMap _msghandlers;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: PlaceRegistry.java,v 1.20 2002/04/15 16:28:01 shaper Exp $
|
||||
// $Id: PlaceRegistry.java,v 1.21 2002/08/14 19:07:49 mdb Exp $
|
||||
|
||||
package com.threerings.crowd.server;
|
||||
|
||||
@@ -43,17 +43,23 @@ public class PlaceRegistry
|
||||
public void placeCreated (PlaceObject place, PlaceManager pmgr);
|
||||
}
|
||||
|
||||
/** The location provider used by the place registry to provide
|
||||
* location-related invocation services. */
|
||||
public LocationProvider locprov;
|
||||
|
||||
/**
|
||||
* Creates and initializes the place registry; called by the server
|
||||
* during its initialization phase.
|
||||
*/
|
||||
public PlaceRegistry (InvocationManager invmgr, RootDObjectManager omgr)
|
||||
{
|
||||
// we'll need this later
|
||||
_omgr = omgr;
|
||||
// create and register our location provider
|
||||
locprov = new LocationProvider(invmgr, omgr, this);
|
||||
invmgr.registerDispatcher(new LocationDispatcher(locprov), true);
|
||||
|
||||
// register the location provider
|
||||
LocationProvider.init(invmgr, omgr, this);
|
||||
// we'll need these later
|
||||
_omgr = omgr;
|
||||
_invmgr = invmgr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +92,7 @@ public class PlaceRegistry
|
||||
// create a place manager for this place
|
||||
PlaceManager pmgr = (PlaceManager)pmgrClass.newInstance();
|
||||
// let the pmgr know about us and its configuration
|
||||
pmgr.init(this, config, _omgr);
|
||||
pmgr.init(this, _invmgr, _omgr, config);
|
||||
|
||||
// stick the manager on the creation queue because we know
|
||||
// we'll get our calls to objectAvailable()/requestFailed() in
|
||||
@@ -221,6 +227,9 @@ public class PlaceRegistry
|
||||
}
|
||||
}
|
||||
|
||||
/** The invocation manager with which we operate. */
|
||||
protected InvocationManager _invmgr;
|
||||
|
||||
/** The distributed object manager with which we operate. */
|
||||
protected RootDObjectManager _omgr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user