From b9dfc6902e202c16c391ac039c5f7d009b822b34 Mon Sep 17 00:00:00 2001 From: Par Winzell Date: Mon, 29 Nov 2010 21:10:57 +0000 Subject: [PATCH] Stop assuming that the ClientObject we log in with is also the BodyObject we walk around with. This patch removes lots of casts strewn about and replaces them with calls to a new function on BodyLocator, which should be subclassed and overridden by those who wish to venture in these new exciting waters. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6308 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../crowd/chat/server/ChatChannelManager.java | 8 ++++++-- .../crowd/chat/server/ChatProvider.java | 6 +++--- .../crowd/chat/server/SpeakHandler.java | 13 ++++++++---- .../crowd/peer/server/CrowdPeerManager.java | 6 ++++-- .../threerings/crowd/server/BodyLocator.java | 13 +++++++++++- .../threerings/crowd/server/BodyManager.java | 3 ++- .../crowd/server/CrowdObjectAccess.java | 20 ++++++++++++------- .../threerings/crowd/server/CrowdSession.java | 7 ++++--- .../crowd/server/LocationManager.java | 9 ++++++--- .../threerings/crowd/server/PlaceManager.java | 19 ++++++++++++------ 10 files changed, 72 insertions(+), 32 deletions(-) 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;