From fec48b858697ae8ac00d1c50dec909ab418bb8e6 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Sat, 26 Oct 2002 02:40:30 +0000 Subject: [PATCH] Track a user's connection status in their occupant info so that we can react to player disconnection, idle (implementation still pending), and reconnection appropriately. Added PlaceManager.bodyUpdated(). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1831 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/crowd/data/OccupantInfo.java | 14 ++++- .../threerings/crowd/server/CrowdClient.java | 57 +++++++++++++++++-- .../threerings/crowd/server/PlaceManager.java | 39 ++++++++++++- .../crowd/server/PlaceManagerDelegate.java | 10 +++- .../presents/server/PresentsClient.java | 13 +++-- 5 files changed, 118 insertions(+), 15 deletions(-) diff --git a/src/java/com/threerings/crowd/data/OccupantInfo.java b/src/java/com/threerings/crowd/data/OccupantInfo.java index 0145cf7c6..1045cfe72 100644 --- a/src/java/com/threerings/crowd/data/OccupantInfo.java +++ b/src/java/com/threerings/crowd/data/OccupantInfo.java @@ -1,5 +1,5 @@ // -// $Id: OccupantInfo.java,v 1.9 2002/08/14 19:07:49 mdb Exp $ +// $Id: OccupantInfo.java,v 1.10 2002/10/26 02:40:30 shaper Exp $ package com.threerings.crowd.data; @@ -27,12 +27,24 @@ import com.threerings.presents.dobj.DSet; public class OccupantInfo extends SimpleStreamableObject implements DSet.Entry, Cloneable { + /** Constant value for {@link #status}. */ + public static final byte ACTIVE = 0; + + /** Constant value for {@link #status}. */ + public static final byte IDLE = 1; + + /** Constant value for {@link #status}. */ + public static final byte DISCONNECTED = 2; + /** The body object id of this occupant (and our entry key). */ public Integer bodyOid; /** The username of this occupant. */ public String username; + /** The status of this occupant. */ + public byte status = ACTIVE; + /** Access to the body object id as an int. */ public int getBodyOid () { diff --git a/src/java/com/threerings/crowd/server/CrowdClient.java b/src/java/com/threerings/crowd/server/CrowdClient.java index 346ef44b0..73da2c3d7 100644 --- a/src/java/com/threerings/crowd/server/CrowdClient.java +++ b/src/java/com/threerings/crowd/server/CrowdClient.java @@ -1,16 +1,63 @@ // -// $Id: CrowdClient.java,v 1.10 2002/09/19 23:36:59 mdb Exp $ +// $Id: CrowdClient.java,v 1.11 2002/10/26 02:40:30 shaper Exp $ package com.threerings.crowd.server; import com.threerings.presents.server.PresentsClient; +import com.threerings.crowd.data.BodyObject; +import com.threerings.crowd.data.OccupantInfo; +import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.server.CrowdServer; + /** - * The crowd client extends the presents client but doesn't really do - * anything at present. It exists mainly so that implementation systems - * will extend it and ensure that we have the option of adding - * functionality here in the future. + * The crowd client extends the presents client with crowd-specific client + * handling. */ public class CrowdClient extends PresentsClient { + // documentation inherited + protected void wasUnmapped () + { + super.wasUnmapped(); + + if (_clobj != null) { + BodyObject bobj = (BodyObject)_clobj; + + // get the location the user is occupying + PlaceObject plobj = (PlaceObject) + CrowdServer.omgr.getObject(bobj.location); + if (plobj != null) { + // update their occupant info with their new connection + // status + OccupantInfo info = (OccupantInfo)plobj.occupantInfo.get( + new Integer(bobj.getOid())); + if (info != null) { + info.status = OccupantInfo.DISCONNECTED; + plobj.updateOccupantInfo(info); + } + } + } + } + + // documentation inherited + protected void sessionWillResume () + { + super.sessionWillResume(); + + BodyObject bobj = (BodyObject)_clobj; + + // get the location the user is occupying + PlaceObject plobj = (PlaceObject) + CrowdServer.omgr.getObject(bobj.location); + if (plobj != null) { + // update their occupant info with their new connection status + OccupantInfo info = (OccupantInfo)plobj.occupantInfo.get( + new Integer(bobj.getOid())); + if (info != null) { + info.status = OccupantInfo.ACTIVE; + plobj.updateOccupantInfo(info); + } + } + } } diff --git a/src/java/com/threerings/crowd/server/PlaceManager.java b/src/java/com/threerings/crowd/server/PlaceManager.java index 7a1ffb819..df46260f5 100644 --- a/src/java/com/threerings/crowd/server/PlaceManager.java +++ b/src/java/com/threerings/crowd/server/PlaceManager.java @@ -1,5 +1,5 @@ // -// $Id: PlaceManager.java,v 1.38 2002/10/06 03:31:16 mdb Exp $ +// $Id: PlaceManager.java,v 1.39 2002/10/26 02:40:30 shaper Exp $ package com.threerings.crowd.server; @@ -14,6 +14,9 @@ import com.threerings.presents.server.InvocationManager; import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObjectManager; +import com.threerings.presents.dobj.EntryAddedEvent; +import com.threerings.presents.dobj.EntryRemovedEvent; +import com.threerings.presents.dobj.EntryUpdatedEvent; import com.threerings.presents.dobj.MessageEvent; import com.threerings.presents.dobj.MessageListener; import com.threerings.presents.dobj.ObjectAddedEvent; @@ -21,6 +24,7 @@ import com.threerings.presents.dobj.ObjectDeathListener; import com.threerings.presents.dobj.ObjectDestroyedEvent; import com.threerings.presents.dobj.ObjectRemovedEvent; import com.threerings.presents.dobj.OidListListener; +import com.threerings.presents.dobj.SetListener; import com.threerings.crowd.Log; import com.threerings.crowd.data.BodyObject; @@ -53,7 +57,7 @@ import com.threerings.crowd.chat.SpeakProvider; */ public class PlaceManager implements MessageListener, OidListListener, ObjectDeathListener, - SpeakProvider.SpeakerValidator + SetListener, SpeakProvider.SpeakerValidator { /** * An interface used to allow the registration of standard message @@ -381,6 +385,19 @@ public class PlaceManager } } + /** + * Called when a body's occupant info is updated. + */ + protected void bodyUpdated (final OccupantInfo info) + { + // let our delegates know what's up + applyToDelegates(new DelegateOp() { + public void apply (PlaceManagerDelegate delegate) { + delegate.bodyUpdated(info); + } + }); + } + /** * Called when we transition from having bodies in the place to not * having any bodies in the place. Some places may take this as a sign @@ -471,6 +488,24 @@ public class PlaceManager didShutdown(); } + // documentation inherited from interface + public void entryAdded (EntryAddedEvent event) + { + } + + // documentation inherited from interface + public void entryUpdated (EntryUpdatedEvent event) + { + if (event.getName().equals(PlaceObject.OCCUPANT_INFO)) { + bodyUpdated((OccupantInfo)event.getEntry()); + } + } + + // documentation inherited from interface + public void entryRemoved (EntryRemovedEvent event) + { + } + // documentation inherited from interface public boolean isValidSpeaker (DObject speakObj, ClientObject speaker) { diff --git a/src/java/com/threerings/crowd/server/PlaceManagerDelegate.java b/src/java/com/threerings/crowd/server/PlaceManagerDelegate.java index 5d0970401..1b70ec0f2 100644 --- a/src/java/com/threerings/crowd/server/PlaceManagerDelegate.java +++ b/src/java/com/threerings/crowd/server/PlaceManagerDelegate.java @@ -1,8 +1,9 @@ // -// $Id: PlaceManagerDelegate.java,v 1.1 2002/02/13 03:21:28 mdb Exp $ +// $Id: PlaceManagerDelegate.java,v 1.2 2002/10/26 02:40:30 shaper Exp $ package com.threerings.crowd.server; +import com.threerings.crowd.data.OccupantInfo; import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceObject; @@ -64,6 +65,13 @@ public class PlaceManagerDelegate { } + /** + * Called when a body occupant info is updated. + */ + public void bodyUpdated (OccupantInfo info) + { + } + /** * Called when the last body leaves the place. */ diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java index 30287bfc4..94f1e651d 100644 --- a/src/java/com/threerings/presents/server/PresentsClient.java +++ b/src/java/com/threerings/presents/server/PresentsClient.java @@ -1,5 +1,5 @@ // -// $Id: PresentsClient.java,v 1.41 2002/09/26 17:49:36 mdb Exp $ +// $Id: PresentsClient.java,v 1.42 2002/10/26 02:40:30 shaper Exp $ package com.threerings.presents.server; @@ -275,10 +275,8 @@ public class PresentsClient // we need to get onto the distributed object thread so that we // can finalize the resumption of the session. we do so by // posting a special event - DEvent event = new DEvent(0) - { - public boolean applyToObject (DObject target) - { + DEvent event = new DEvent(0) { + public boolean applyToObject (DObject target) { // now that we're on the dobjmgr thread we can resume our // session resumption finishResumeSession(); @@ -426,6 +424,9 @@ public class PresentsClient // then let the client manager know what's up (it will take care // of destroying our client object for us) _cmgr.clientDidEndSession(this); + + // clear out the client object so that we know the session is over + _clobj = null; } /** @@ -549,7 +550,7 @@ public class PresentsClient MessageDispatcher disp = (MessageDispatcher) _disps.get(message.getClass()); if (disp == null) { - Log.warning("No dispacther for message [msg=" + message + "]."); + Log.warning("No dispatcher for message [msg=" + message + "]."); return; }