Added more sanity checking to portal traversal to avoid spurious error

messages if repeat requests come in or for some reason the client and
server ever differ in opinion as to which scene the player is in.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3363 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2005-02-22 18:54:48 +00:00
parent 7ec0eeca56
commit 53be9a74ca
5 changed files with 37 additions and 13 deletions
@@ -43,6 +43,7 @@ import com.threerings.crowd.data.PlaceObject;
import com.threerings.whirled.client.SceneDirector;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.data.ScenedBodyObject;
import com.threerings.whirled.util.WhirledContext;
import com.threerings.whirled.spot.Log;
@@ -133,6 +134,18 @@ public class SpotSceneDirector extends BasicDirector
return false;
}
// sanity check the server's notion of what scene we're in with
// our notion of it
int sceneId = _scdir.getScene().getId();
ScenedBodyObject sbobj = (ScenedBodyObject)
_ctx.getClient().getClientObject();
if (sceneId != sbobj.getSceneId()) {
Log.warning("Client and server differ in opinion of what scene " +
"we're in [sSceneId=" + sbobj.getSceneId() +
", cSceneId=" + sceneId + "].");
return false;
}
// find the portal they're talking about
Portal dest = scene.getPortal(portalId);
if (dest == null) {
@@ -159,8 +172,10 @@ public class SpotSceneDirector extends BasicDirector
}
// issue a traversePortal request
Log.info("Issuing traversePortal(" + dest + ", " + sceneVer + ").");
_sservice.traversePortal(_ctx.getClient(), portalId, sceneVer, _scdir);
Log.info("Issuing traversePortal(" +
sceneId + ", " + dest + ", " + sceneVer + ").");
_sservice.traversePortal(
_ctx.getClient(), sceneId, portalId, sceneVer, _scdir);
return true;
}
@@ -38,12 +38,14 @@ public interface SpotService extends InvocationService
/**
* Requests to traverse the specified portal.
*
* @param sceneId the player's current scene which is used to sanity
* check things when the request actually arrives.
* @param portalId the portal to be traversed.
* @param destSceneVer the version of the destination scene data that
* the client has in its local repository.
*/
public void traversePortal (
Client client, int portalId, int destSceneVer,
Client client, int sceneId, int portalId, int destSceneVer,
SceneMoveListener listener);
/**
@@ -2,7 +2,7 @@
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
@@ -81,12 +81,12 @@ public class SpotMarshaller extends InvocationMarshaller
public static final int TRAVERSE_PORTAL = 4;
// documentation inherited from interface
public void traversePortal (Client arg1, int arg2, int arg3, SceneService.SceneMoveListener arg4)
public void traversePortal (Client arg1, int arg2, int arg3, int arg4, SceneService.SceneMoveListener arg5)
{
SceneMarshaller.SceneMoveMarshaller listener4 = new SceneMarshaller.SceneMoveMarshaller();
listener4.listener = arg4;
SceneMarshaller.SceneMoveMarshaller listener5 = new SceneMarshaller.SceneMoveMarshaller();
listener5.listener = arg5;
sendRequest(arg1, TRAVERSE_PORTAL, new Object[] {
new Integer(arg2), new Integer(arg3), listener4
new Integer(arg2), new Integer(arg3), new Integer(arg4), listener5
});
}
@@ -2,7 +2,7 @@
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
@@ -83,7 +83,7 @@ public class SpotDispatcher extends InvocationDispatcher
case SpotMarshaller.TRAVERSE_PORTAL:
((SpotProvider)provider).traversePortal(
source,
((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (SceneService.SceneMoveListener)args[2]
((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue(), (SceneService.SceneMoveListener)args[3]
);
return;
@@ -1,5 +1,5 @@
//
// $Id: SpotProvider.java,v 1.25 2004/08/27 02:20:47 mdb Exp $
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
@@ -77,11 +77,18 @@ public class SpotProvider
/**
* Processes a {@link SpotService#traversePortal} request.
*/
public void traversePortal (ClientObject caller, int portalId,
public void traversePortal (ClientObject caller, int sceneId, int portalId,
int destSceneVer, SceneMoveListener listener)
throws InvocationException
{
int sceneId = getCallerSceneId(caller);
// le sanity check
int cSceneId = getCallerSceneId(caller);
if (cSceneId != sceneId) {
Log.info("Ignoring stale traverse portal request " +
"[caller=" + caller.who() + ", oSceneId=" + sceneId +
", portalId=" + portalId + ", cSceneId=" + cSceneId + "].");
return;
}
// avoid cluttering up the method declaration with final keywords
final BodyObject fsource = (BodyObject)caller;