diff --git a/src/main/java/com/threerings/crowd/chat/server/ChatChannelManager.java b/src/main/java/com/threerings/crowd/chat/server/ChatChannelManager.java index cf694c7e9..a9860d4fb 100644 --- a/src/main/java/com/threerings/crowd/chat/server/ChatChannelManager.java +++ b/src/main/java/com/threerings/crowd/chat/server/ChatChannelManager.java @@ -62,6 +62,7 @@ import com.threerings.crowd.data.CrowdCodes; import com.threerings.crowd.peer.data.CrowdClientInfo; import com.threerings.crowd.peer.data.CrowdNodeObject; import com.threerings.crowd.peer.server.CrowdPeerManager; +import com.threerings.crowd.server.BodyLocator; import static com.threerings.crowd.Log.log; @@ -132,8 +133,8 @@ public abstract class ChatChannelManager // from interface ChannelSpeakProvider public void speak (ClientObject caller, final ChatChannel channel, String message, byte mode) { - final UserMessage umsg = new UserMessage( - ((BodyObject)caller).getVisibleName(), null, message, mode); + BodyObject body = _locator.forClient(caller); + final UserMessage umsg = new UserMessage(body.getVisibleName(), null, message, mode); // if we're hosting this channel, dispatch it directly if (_channels.containsKey(channel)) { @@ -495,6 +496,9 @@ public abstract class ChatChannelManager /** Provides peer services. */ @Inject protected CrowdPeerManager _peerMan; + /** Used for acquiring BodyObject references from Names and ClientObjects. */ + @Inject protected BodyLocator _locator; + /** The period on which we check for idle channels. */ protected static final long IDLE_CHANNEL_CHECK_PERIOD = 5 * 1000L; diff --git a/src/main/java/com/threerings/crowd/chat/server/ChatProvider.java b/src/main/java/com/threerings/crowd/chat/server/ChatProvider.java index f88a9fdba..5e8a6b485 100644 --- a/src/main/java/com/threerings/crowd/chat/server/ChatProvider.java +++ b/src/main/java/com/threerings/crowd/chat/server/ChatProvider.java @@ -136,7 +136,7 @@ public class ChatProvider InvocationException.requireAccess(caller, ChatCodes.CHAT_ACCESS); // deliver the tell message to the target - BodyObject source = (BodyObject)caller; + BodyObject source = _locator.forClient(caller); deliverTell(createTellMessage(source, message), target, listener); // inform the auto-responder if needed @@ -154,7 +154,7 @@ public class ChatProvider { // make sure the requesting user has broadcast privileges InvocationException.requireAccess(caller, ChatCodes.BROADCAST_ACCESS); - BodyObject body = (BodyObject)caller; + BodyObject body = _locator.forClient(caller); broadcast(body.getVisibleName(), null, message, false, true); } @@ -163,7 +163,7 @@ public class ChatProvider */ public void away (ClientObject caller, String message) { - BodyObject body = (BodyObject)caller; + BodyObject body = _locator.forClient(caller); // we modify this field via an invocation service request because a body object is not // modifiable by the client body.setAwayMessage(message); diff --git a/src/main/java/com/threerings/crowd/chat/server/SpeakHandler.java b/src/main/java/com/threerings/crowd/chat/server/SpeakHandler.java index 3b6541098..154c3432a 100644 --- a/src/main/java/com/threerings/crowd/chat/server/SpeakHandler.java +++ b/src/main/java/com/threerings/crowd/chat/server/SpeakHandler.java @@ -30,6 +30,7 @@ import com.threerings.presents.server.InvocationManager; import com.threerings.crowd.chat.client.SpeakService; import com.threerings.crowd.chat.data.ChatCodes; import com.threerings.crowd.data.BodyObject; +import com.threerings.crowd.server.BodyLocator; import static com.threerings.crowd.Log.log; @@ -62,8 +63,9 @@ public class SpeakHandler * @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) + public SpeakHandler (BodyLocator locator, DObject speakObj, SpeakerValidator validator) { + _locator = locator; _speakObj = speakObj; _validator = validator; } @@ -72,11 +74,11 @@ public class SpeakHandler 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); + BodyObject source = _locator.forClient(caller); + String errmsg = caller.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 + // InvocationException, we have to specifically communicate the error to the user SpeakUtil.sendFeedback(source, MessageManager.GLOBAL_BUNDLE, errmsg); return; } @@ -96,6 +98,9 @@ public class SpeakHandler } } + /** Used for acquiring BodyObject references from Names and ClientObjects. */ + protected BodyLocator _locator; + /** Our speech object. */ protected DObject _speakObj; diff --git a/src/main/java/com/threerings/crowd/peer/server/CrowdPeerManager.java b/src/main/java/com/threerings/crowd/peer/server/CrowdPeerManager.java index 4b717cfed..29c5907ec 100644 --- a/src/main/java/com/threerings/crowd/peer/server/CrowdPeerManager.java +++ b/src/main/java/com/threerings/crowd/peer/server/CrowdPeerManager.java @@ -41,6 +41,7 @@ import com.threerings.crowd.chat.server.ChatProvider; import com.threerings.crowd.data.BodyObject; import com.threerings.crowd.peer.data.CrowdClientInfo; import com.threerings.crowd.peer.data.CrowdNodeObject; +import com.threerings.crowd.server.BodyLocator; /** * Extends the standard peer manager and bridges certain Crowd services. @@ -140,8 +141,8 @@ public abstract class CrowdPeerManager extends PeerManager protected void initClientInfo (PresentsSession client, ClientInfo info) { super.initClientInfo(client, info); - ((CrowdClientInfo)info).visibleName = - ((BodyObject)client.getClientObject()).getVisibleName(); + BodyObject body = _locator.forClient(client.getClientObject()); + ((CrowdClientInfo)info).visibleName = body.getVisibleName(); } @Override // from PeerManager @@ -164,4 +165,5 @@ public abstract class CrowdPeerManager extends PeerManager protected abstract Name authFromViz (Name vizname); @Inject protected ChatProvider _chatprov; + @Inject protected BodyLocator _locator; } diff --git a/src/main/java/com/threerings/crowd/server/BodyLocator.java b/src/main/java/com/threerings/crowd/server/BodyLocator.java index b566b34b7..fe670dd44 100644 --- a/src/main/java/com/threerings/crowd/server/BodyLocator.java +++ b/src/main/java/com/threerings/crowd/server/BodyLocator.java @@ -24,6 +24,7 @@ package com.threerings.crowd.server; import com.google.inject.Inject; import com.google.inject.Singleton; +import com.threerings.presents.data.ClientObject; import com.threerings.util.Name; import com.threerings.presents.annotation.EventThread; @@ -45,7 +46,17 @@ public class BodyLocator public BodyObject lookupBody (Name visibleName) { // by default visibleName is username - return (BodyObject)_clmgr.getClientObject(visibleName); + return forClient(_clmgr.getClientObject(visibleName)); + } + + /** + * Returns the body object to be used for the given client. The default implementation + * assumes they are one and the same. + */ + @EventThread + public BodyObject forClient (ClientObject client) + { + return (BodyObject)client; } @Inject protected ClientManager _clmgr; diff --git a/src/main/java/com/threerings/crowd/server/BodyManager.java b/src/main/java/com/threerings/crowd/server/BodyManager.java index 2154313f1..e4f010c04 100644 --- a/src/main/java/com/threerings/crowd/server/BodyManager.java +++ b/src/main/java/com/threerings/crowd/server/BodyManager.java @@ -87,7 +87,7 @@ public class BodyManager // from interface BodyProvider public void setIdle (ClientObject caller, boolean idle) { - BodyObject bobj = (BodyObject)caller; + BodyObject bobj = _locator.forClient(caller); // determine the body's proposed new status byte nstatus = (idle) ? OccupantInfo.IDLE : OccupantInfo.ACTIVE; @@ -102,4 +102,5 @@ public class BodyManager /** Provides access to place managers. */ @Inject protected PlaceRegistry _plreg; + @Inject protected BodyLocator _locator; } diff --git a/src/main/java/com/threerings/crowd/server/CrowdObjectAccess.java b/src/main/java/com/threerings/crowd/server/CrowdObjectAccess.java index d4efc7268..28fe118ac 100644 --- a/src/main/java/com/threerings/crowd/server/CrowdObjectAccess.java +++ b/src/main/java/com/threerings/crowd/server/CrowdObjectAccess.java @@ -32,6 +32,9 @@ import com.threerings.presents.server.PresentsObjectAccess; import com.threerings.bureau.data.BureauClientObject; import com.threerings.crowd.data.PlaceObject; +import com.google.inject.Inject; +import com.google.inject.Singleton; + /** * Defines the various object access controllers used by the Crowd server. */ @@ -42,29 +45,32 @@ public class CrowdObjectAccess * to subscribe to the place object and to use the {@link PresentsObjectAccess#DEFAULT} * modification policy. */ - public static AccessController PLACE = new AccessController() + @Singleton + public static class PlaceAccessController implements AccessController { - // documentation inherited from interface public boolean allowSubscribe (DObject object, Subscriber sub) { if (sub instanceof ProxySubscriber) { ClientObject co = ((ProxySubscriber)sub).getClientObject(); - return ((PlaceObject)object).occupants.contains(co.getOid()); + return ((PlaceObject)object).occupants.contains(_locator.forClient(co).getOid()); } return true; } - // documentation inherited from interface public boolean allowDispatch (DObject object, DEvent event) { return PresentsObjectAccess.DEFAULT.allowDispatch(object, event); } + + @Inject protected BodyLocator _locator; }; /** * Extends the access control in {@link #PLACE} to allow Bureau clients to subscribe. */ - public static AccessController BUREAU_ACCESS_PLACE = new AccessController() { + @Singleton + public static class BureauAccessController extends PlaceAccessController + { public boolean allowSubscribe (DObject object, Subscriber sub) { if (sub instanceof ProxySubscriber) { ClientObject co = ((ProxySubscriber)sub).getClientObject(); @@ -72,10 +78,10 @@ public class CrowdObjectAccess return true; } } - return PLACE.allowSubscribe(object, sub); + return super.allowSubscribe(object, sub); } public boolean allowDispatch (DObject object, DEvent event) { - return PLACE.allowDispatch(object, event); + return super.allowDispatch(object, event); } }; diff --git a/src/main/java/com/threerings/crowd/server/CrowdSession.java b/src/main/java/com/threerings/crowd/server/CrowdSession.java index 962232e52..ac7243787 100644 --- a/src/main/java/com/threerings/crowd/server/CrowdSession.java +++ b/src/main/java/com/threerings/crowd/server/CrowdSession.java @@ -41,7 +41,7 @@ public class CrowdSession extends PresentsSession if (_clobj != null) { // note that the user is disconnected - BodyObject bobj = (BodyObject)_clobj; + BodyObject bobj = _locator.forClient(_clobj); _bodyman.updateOccupantStatus(bobj, OccupantInfo.DISCONNECTED); } } @@ -52,7 +52,7 @@ public class CrowdSession extends PresentsSession super.sessionWillResume(); // note that the user's active once more - BodyObject bobj = (BodyObject)_clobj; + BodyObject bobj = _locator.forClient(_clobj); _bodyman.updateOccupantStatus(bobj, OccupantInfo.ACTIVE); } @@ -61,7 +61,7 @@ public class CrowdSession extends PresentsSession { super.sessionDidEnd(); - BodyObject body = (BodyObject)_clobj; + BodyObject body = _locator.forClient(_clobj); // clear out our location so that anyone listening will know that we've left clearLocation(body); @@ -87,6 +87,7 @@ public class CrowdSession extends PresentsSession _locman.leaveOccupiedPlace(bobj); } + @Inject protected BodyLocator _locator; @Inject protected BodyManager _bodyman; @Inject protected LocationManager _locman; } diff --git a/src/main/java/com/threerings/crowd/server/LocationManager.java b/src/main/java/com/threerings/crowd/server/LocationManager.java index dd1de8c52..9b726f2bd 100644 --- a/src/main/java/com/threerings/crowd/server/LocationManager.java +++ b/src/main/java/com/threerings/crowd/server/LocationManager.java @@ -57,13 +57,15 @@ public class LocationManager throws InvocationException { // do the move and send the response - listener.moveSucceeded(moveTo((BodyObject)caller, placeOid)); + BodyObject body = _locator.forClient(caller); + listener.moveSucceeded(moveTo(body, placeOid)); } // from interface LocationProvider public void leavePlace (ClientObject caller) { - leaveOccupiedPlace((BodyObject)caller); + BodyObject body = _locator.forClient(caller); + leaveOccupiedPlace(body); } /** @@ -180,6 +182,7 @@ public class LocationManager } @Inject protected RootDObjectManager _omgr; - @Inject protected PlaceRegistry _plreg; + @Inject protected BodyLocator _locator; @Inject protected ClientManager _clmgr; + @Inject protected PlaceRegistry _plreg; } diff --git a/src/main/java/com/threerings/crowd/server/PlaceManager.java b/src/main/java/com/threerings/crowd/server/PlaceManager.java index 4fd2cdf8c..09e8668be 100644 --- a/src/main/java/com/threerings/crowd/server/PlaceManager.java +++ b/src/main/java/com/threerings/crowd/server/PlaceManager.java @@ -60,6 +60,10 @@ import com.threerings.crowd.data.OccupantInfo; import com.threerings.crowd.data.Place; import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.server.CrowdObjectAccess.PlaceAccessController; + +import com.google.inject.Inject; +import com.google.inject.Injector; import static com.threerings.crowd.Log.log; @@ -509,7 +513,7 @@ public class PlaceManager */ protected AccessController getAccessController () { - return CrowdObjectAccess.PLACE; + return _injector.getInstance(PlaceAccessController.class); } /** @@ -729,7 +733,7 @@ public class PlaceManager */ protected SpeakHandler createSpeakHandler (PlaceObject plobj) { - return new SpeakHandler(plobj, this); + return new SpeakHandler(_locator, plobj, this); } /** Listens for occupant updates. */ @@ -770,17 +774,20 @@ public class PlaceManager } }; + /** We use this to inject dependencies into our access controller. */ + @Inject protected Injector _injector; + /** A reference to the place registry with which we're registered. */ - protected PlaceRegistry _registry; + @Inject protected PlaceRegistry _registry; /** The invocation manager with whom we register our game invocation services. */ - protected InvocationManager _invmgr; + @Inject protected InvocationManager _invmgr; /** A distributed object manager for doing dobj stuff. */ - protected RootDObjectManager _omgr; + @Inject protected RootDObjectManager _omgr; /** Used to look up body objects by name. */ - protected BodyLocator _locator; + @Inject protected BodyLocator _locator; /** A reference to the place object that we manage. */ protected PlaceObject _plobj;