From f76825c76ed6e2d6893269380f0b8a852a5a7cb3 Mon Sep 17 00:00:00 2001 From: Elizabeth Fong Date: Tue, 27 Mar 2007 21:11:13 +0000 Subject: [PATCH] Fix yohoho singleplayer NPE boochery caused by unsafe direct call on DObjectManager git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4636 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/crowd/data/PlaceObject.java | 28 +++++++++++++++++-- .../threerings/presents/client/Client.java | 2 ++ .../presents/server/LocalDObjectMgr.java | 5 +++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/java/com/threerings/crowd/data/PlaceObject.java b/src/java/com/threerings/crowd/data/PlaceObject.java index 9f36c4f1f..bd9b6718b 100644 --- a/src/java/com/threerings/crowd/data/PlaceObject.java +++ b/src/java/com/threerings/crowd/data/PlaceObject.java @@ -26,8 +26,11 @@ import java.util.Iterator; import com.threerings.util.Name; import com.threerings.presents.dobj.DObject; +import com.threerings.presents.dobj.DObjectManager; import com.threerings.presents.dobj.DSet; +import com.threerings.presents.dobj.MessageEvent; import com.threerings.presents.dobj.OidList; +import com.threerings.presents.server.LocalDObjectMgr; import com.threerings.crowd.Log; import com.threerings.crowd.chat.data.SpeakMarshaller; @@ -54,14 +57,33 @@ public class PlaceObject extends DObject // AUTO-GENERATED: FIELDS END /** - * Exists solely to make calls into the manager look sensible: + * Exists solely to make calls into the client's DObjManager look sensible: *
_plobj.manager.invoke("someMethod", args);
*/ public class ManagerCaller { - public void invoke (String method, Object ... args) { - postMessage(method, args); + + public ManagerCaller () + { + // Avoid NPE boochery if we're in singleplayer mode in yohoho: + // It turns out that GameController posts events directly to the queue + // of the DObjectManager of the GameObject, which is in this case the + // DObjectManager instead of the ClientDObjectMgr, so the sourceOid is + // unchanged, leading to the nasty problem of caller being null as the + // message was not actually received from any connected outside client. + DObjectManager clomgr = LocalDObjectMgr.clomgr; + if (clomgr != null) { + _mgr = clomgr; + } else { + _mgr = PlaceObject.this.getManager(); + } } + + public void invoke (String method, Object ... args) { + _mgr.postEvent(new MessageEvent(_oid, method, args)); + } + + protected DObjectManager _mgr; } /** diff --git a/src/java/com/threerings/presents/client/Client.java b/src/java/com/threerings/presents/client/Client.java index 9fb8dd5b1..1974fbf7b 100644 --- a/src/java/com/threerings/presents/client/Client.java +++ b/src/java/com/threerings/presents/client/Client.java @@ -37,6 +37,7 @@ import com.threerings.presents.net.BootstrapData; import com.threerings.presents.net.Credentials; import com.threerings.presents.net.PingRequest; import com.threerings.presents.net.PongResponse; +import com.threerings.presents.server.LocalDObjectMgr; /** * Through the client object, a connection to the system is established and maintained. The client @@ -619,6 +620,7 @@ public class Client // clear out our references _comm = null; _omgr = null; + LocalDObjectMgr.clomgr = null; _clobj = null; _cloid = -1; _standalone = false; diff --git a/src/java/com/threerings/presents/server/LocalDObjectMgr.java b/src/java/com/threerings/presents/server/LocalDObjectMgr.java index 2c0817214..788e50b64 100644 --- a/src/java/com/threerings/presents/server/LocalDObjectMgr.java +++ b/src/java/com/threerings/presents/server/LocalDObjectMgr.java @@ -45,7 +45,7 @@ public class LocalDObjectMgr extends PresentsDObjectMgr */ public DObjectManager getClientDObjectMgr (final int clientOid) { - return new DObjectManager() { + clomgr = new DObjectManager() { public boolean isManager (DObject object) { return LocalDObjectMgr.this.isManager(object); } @@ -65,6 +65,7 @@ public class LocalDObjectMgr extends PresentsDObjectMgr LocalDObjectMgr.this.removedLastSubscriber(obj, deathWish); } }; + return clomgr; } // documentation inherited @@ -92,4 +93,6 @@ public class LocalDObjectMgr extends PresentsDObjectMgr // accounting data EventQueue.invokeLater(unit); } + + public static DObjectManager clomgr = null; }