From 877892b4c85b434aeb6f1f5bdef3595719da52be Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 15 Feb 2005 00:58:16 +0000 Subject: [PATCH] Allow the ZoneManager to veto a body's departure from the zone. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3350 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../whirled/zone/server/ZoneManager.java | 16 ++++++- .../whirled/zone/server/ZoneProvider.java | 47 +++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/java/com/threerings/whirled/zone/server/ZoneManager.java b/src/java/com/threerings/whirled/zone/server/ZoneManager.java index 3b7e7843d..3f9dda19e 100644 --- a/src/java/com/threerings/whirled/zone/server/ZoneManager.java +++ b/src/java/com/threerings/whirled/zone/server/ZoneManager.java @@ -1,5 +1,5 @@ // -// $Id: ZoneManager.java,v 1.4 2004/08/27 02:20:51 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -23,6 +23,7 @@ package com.threerings.whirled.zone.server; import com.threerings.crowd.data.BodyObject; import com.threerings.whirled.zone.data.ZoneSummary; +import com.threerings.whirled.zone.data.ZonedBodyObject; /** * A zone is a collection of scenes organized into a connected group. A @@ -63,6 +64,19 @@ public interface ZoneManager */ public void resolveZone (int zoneId, ResolutionListener listener); + /** + * Called when a body has requested to leave a zone. The zone manager + * may return null to indicate that the body is allowed to leave the + * current zone or a string error code indicating the reason for + * denial of access (which will be propagated back to the requesting + * client). + * + * @param body the body object of the user that desires to depart + * their current zone (which can be obtained by casting the {@link + * BodyObject} to a {@link ZonedBodyObject}). + */ + public String ratifyBodyExit (BodyObject body); + /** * Called when a body has requested to enter a zone. The zone manager * may return null to indicate that the body is allowed access to the diff --git a/src/java/com/threerings/whirled/zone/server/ZoneProvider.java b/src/java/com/threerings/whirled/zone/server/ZoneProvider.java index c93ff8c47..07ab3f248 100644 --- a/src/java/com/threerings/whirled/zone/server/ZoneProvider.java +++ b/src/java/com/threerings/whirled/zone/server/ZoneProvider.java @@ -1,5 +1,5 @@ // -// $Id: ZoneProvider.java,v 1.19 2004/10/30 04:33:22 mdb Exp $ +// $Id$ // // Narya library - tools for developing networked games // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved @@ -83,6 +83,22 @@ public class ZoneProvider final int fsceneVer = sceneVer; final ZoneMoveListener flistener = listener; + // look up the caller's current zone id and make sure it is happy + // about their departure from the current zone + if (!(caller instanceof ZonedBodyObject)) { + Log.warning("Request to switch zones by non-ZonedBodyObject!? " + + "[clobj=" + caller.getClass() + "]."); + throw new InvocationException(INTERNAL_ERROR); + } + ZonedBodyObject zcaller = (ZonedBodyObject)caller; + ZoneManager ozmgr = _zonereg.getZoneManager(zcaller.getZoneId()); + if (ozmgr != null) { + String msg = ozmgr.ratifyBodyExit(fsource); + if (msg != null) { + throw new InvocationException(msg); + } + } + // look up the zone manager for the zone ZoneManager zmgr = _zonereg.getZoneManager(zoneId); if (zmgr == null) { @@ -216,8 +232,12 @@ public class ZoneProvider * Ejects the specified body from their current scene and sends them a * request to move to the specified new zone and scene. This is the * zone-equivalent to {@link LocationProvider#moveBody}. + * + * @return null if the user was forcibly moved, a string indicating + * the reason for denial of departure of their current zone (from + * {@link ZoneManager#ratifyBodyExit}). */ - public void moveBody (ZonedBodyObject source, int zoneId, int sceneId) + public String moveBody (ZonedBodyObject source, int zoneId, int sceneId) { if (source.getZoneId() == zoneId) { // handle the case of moving somewhere in the same zone @@ -225,25 +245,44 @@ public class ZoneProvider } else { // first remove them from their old location - leaveOccupiedZone(source); + String reason = leaveOccupiedZone(source); + if (reason != null) { + return reason; + } // then send a forced move notification ZoneSender.forcedMove((BodyObject)source, zoneId, sceneId); } + return null; } /** * Ejects the specified body from their current scene and zone. This * is the zone equivalent to {@link * LocationProvider#leaveOccupiedPlace}. + * + * @return null if the user was forcibly moved, a string indicating + * the reason for denial of departure of their current zone (from + * {@link ZoneManager#ratifyBodyExit}). */ - public void leaveOccupiedZone (ZonedBodyObject source) + public String leaveOccupiedZone (ZonedBodyObject source) { + // look up the caller's current zone id and make sure it is happy + // about their departure from the current zone + ZoneManager zmgr = _zonereg.getZoneManager(source.getZoneId()); + String msg; + if (zmgr != null && + (msg = zmgr.ratifyBodyExit((BodyObject)source)) != null) { + return msg; + } + // remove them from their occupied scene _screg.sceneprov.leaveOccupiedScene(source); // and clear out their zone information source.setZoneId(-1); + + return null; } /** The entity that handles basic location changes. */