public void traversePortal (ClientObject caller, int sceneId, int portalId,
int destSceneVer, SpotService.SpotSceneMoveListener listener)
throws InvocationException
{
// le sanity check
BodyObject body = _locator.forClient(caller);
int cSceneId = ScenePlace.getSceneId(body);
if (cSceneId != sceneId) {
log.info("Ignoring stale traverse portal request",
"caller", caller.who(), "oSceneId", sceneId, "portalId", portalId,
"cSceneId", cSceneId);
listener.requestCancelled();
return;
}
// obtain the source scene
SpotSceneManager srcmgr = (SpotSceneManager)getSceneManager(sceneId);
if (srcmgr == null) {
log.warning("Traverse portal missing source scene",
"user", body.who(), "sceneId", sceneId, "portalId", portalId);
throw new InvocationException(SpotCodes.INTERNAL_ERROR);
}
// obtain the destination scene and location id
SpotScene rss = (SpotScene)srcmgr.getScene();
Portal dest = rss.getPortal(portalId);
// give the source scene manager a chance to do access control
String errmsg = srcmgr.mayTraversePortal(body, dest);
if (errmsg != null) {
throw new InvocationException(errmsg);
}
// make sure this portal has valid info
if (dest == null || !dest.isValid()) {
log.warning("Traverse portal with invalid portal",
"user", body.who(), "scene", srcmgr.where(), "pid", portalId, "portal", dest,
"portals", rss.getPortals());
throw new InvocationException(SpotCodes.NO_SUCH_PORTAL);
}
// resolve their destination scene